Initial check in
Bug: 137197907
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2003-11-02-WeakLinkage.cpp b/src/llvm-project/clang/test/CodeGenCXX/2003-11-02-WeakLinkage.cpp
new file mode 100644
index 0000000..02f9fc6
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2003-11-02-WeakLinkage.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
+// The template should compile to linkonce linkage, not weak linkage.
+
+// CHECK-NOT: weak
+template<class T>
+void thefunc();
+
+template<class T>
+inline void thefunc() {}
+
+void test() {
+ thefunc<int>();
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2003-11-18-PtrMemConstantInitializer.cpp b/src/llvm-project/clang/test/CodeGenCXX/2003-11-18-PtrMemConstantInitializer.cpp
new file mode 100644
index 0000000..9cecf48
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2003-11-18-PtrMemConstantInitializer.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -emit-llvm %s -o -
+
+struct Gfx {
+ void opMoveSetShowText();
+};
+
+struct Operator {
+ void (Gfx::*func)();
+};
+
+Operator opTab[] = {
+ {&Gfx::opMoveSetShowText},
+};
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2003-11-27-MultipleInheritanceThunk.cpp b/src/llvm-project/clang/test/CodeGenCXX/2003-11-27-MultipleInheritanceThunk.cpp
new file mode 100644
index 0000000..a70f6e0
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2003-11-27-MultipleInheritanceThunk.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm %s -o -
+// RUN: %clang_cc1 -triple %ms_abi_triple -fno-rtti -emit-llvm %s -o -
+
+
+struct CallSite {
+ int X;
+
+ CallSite(const CallSite &CS);
+};
+
+struct AliasAnalysis {
+ int TD;
+
+ virtual int getModRefInfo(CallSite CS);
+};
+
+
+struct Pass {
+ int X;
+ virtual int foo();
+};
+
+struct AliasAnalysisCounter : public Pass, public AliasAnalysis {
+ int getModRefInfo(CallSite CS) {
+ return 0;
+ }
+};
+
+AliasAnalysisCounter AAC;
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2003-11-29-DuplicatedCleanupTest.cpp b/src/llvm-project/clang/test/CodeGenCXX/2003-11-29-DuplicatedCleanupTest.cpp
new file mode 100644
index 0000000..45325bc
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2003-11-29-DuplicatedCleanupTest.cpp
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -emit-llvm %s -o -
+
+
+void doesntThrow() throw();
+struct F {
+ ~F() { doesntThrow(); }
+};
+
+void atest() {
+ F A;
+lab:
+ F B;
+ goto lab;
+}
+
+void test(int val) {
+label: {
+ F A;
+ F B;
+ if (val == 0) goto label;
+ if (val == 1) goto label;
+}
+}
+
+void test3(int val) {
+label: {
+ F A;
+ F B;
+ if (val == 0) { doesntThrow(); goto label; }
+ if (val == 1) { doesntThrow(); goto label; }
+}
+}
+
+void test4(int val) {
+label: {
+ F A;
+ F B;
+ if (val == 0) { F C; goto label; }
+ if (val == 1) { F D; goto label; }
+}
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2003-12-08-ArrayOfPtrToMemberFunc.cpp b/src/llvm-project/clang/test/CodeGenCXX/2003-12-08-ArrayOfPtrToMemberFunc.cpp
new file mode 100644
index 0000000..38de271
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2003-12-08-ArrayOfPtrToMemberFunc.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -emit-llvm %s -o -
+
+struct Evil {
+ void fun ();
+};
+int foo();
+typedef void (Evil::*memfunptr) ();
+static memfunptr jumpTable[] = { &Evil::fun };
+
+void Evil::fun() {
+ (this->*jumpTable[foo()]) ();
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2004-01-11-DynamicInitializedConstant.cpp b/src/llvm-project/clang/test/CodeGenCXX/2004-01-11-DynamicInitializedConstant.cpp
new file mode 100644
index 0000000..0c9333f
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2004-01-11-DynamicInitializedConstant.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+
+// CHECK-NOT: constant
+extern int X;
+const int Y = X;
+const int* foo() { return &Y; }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2004-03-08-ReinterpretCastCopy.cpp b/src/llvm-project/clang/test/CodeGenCXX/2004-03-08-ReinterpretCastCopy.cpp
new file mode 100644
index 0000000..a4411fc
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2004-03-08-ReinterpretCastCopy.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm %s -o -
+// RUN: %clang_cc1 -triple %ms_abi_triple -fno-rtti -emit-llvm %s -o -
+
+struct A {
+ virtual void Method() = 0;
+};
+
+struct B : public A {
+ virtual void Method() { }
+};
+
+typedef void (A::*fn_type_a)(void);
+typedef void (B::*fn_type_b)(void);
+
+int main(int argc, char **argv)
+{
+ fn_type_a f = reinterpret_cast<fn_type_a>(&B::Method);
+ fn_type_b g = reinterpret_cast<fn_type_b>(f);
+ B b;
+ (b.*g)();
+ return 0;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2004-03-09-UnmangledBuiltinMethods.cpp b/src/llvm-project/clang/test/CodeGenCXX/2004-03-09-UnmangledBuiltinMethods.cpp
new file mode 100644
index 0000000..03c4ed6
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2004-03-09-UnmangledBuiltinMethods.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -o - %s | FileCheck %s
+
+// CHECK: _ZN11AccessFlags6strlenEv
+struct AccessFlags {
+ void strlen();
+};
+
+void AccessFlags::strlen() { }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2004-03-15-CleanupsAndGotos.cpp b/src/llvm-project/clang/test/CodeGenCXX/2004-03-15-CleanupsAndGotos.cpp
new file mode 100644
index 0000000..01350c0
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2004-03-15-CleanupsAndGotos.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -emit-llvm %s -o -
+
+// Testcase from Bug 291
+
+struct X {
+ ~X();
+};
+
+void foo() {
+ X v;
+
+TryAgain:
+ goto TryAgain;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2004-06-08-LateTemplateInstantiation.cpp b/src/llvm-project/clang/test/CodeGenCXX/2004-06-08-LateTemplateInstantiation.cpp
new file mode 100644
index 0000000..97254c1
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2004-06-08-LateTemplateInstantiation.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -emit-llvm %s -o -
+
+
+template<typename Ty>
+struct normal_iterator {
+ int FIELD;
+};
+
+void foo(normal_iterator<int>);
+normal_iterator<int> baz();
+
+void bar() {
+ foo(baz());
+}
+
+void *bar2() {
+ return (void*)foo;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2004-09-27-DidntEmitTemplate.cpp b/src/llvm-project/clang/test/CodeGenCXX/2004-09-27-DidntEmitTemplate.cpp
new file mode 100644
index 0000000..618894f
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2004-09-27-DidntEmitTemplate.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
+
+// This is a testcase for LLVM PR445, which was a problem where the
+// instantiation of callDefaultCtor was not being emitted correctly.
+
+// CHECK-NOT: declare{{.*}}callDefaultCtor
+struct Pass {};
+
+template<typename PassName>
+Pass *callDefaultCtor() { return new Pass(); }
+
+void foo(Pass *(*C)());
+
+struct basic_string {
+ bool empty() const { return true; }
+};
+
+
+bool foo2(basic_string &X) {
+ return X.empty();
+}
+void baz() { foo(callDefaultCtor<Pass>); }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2004-11-27-ExceptionCleanupAssertion.cpp b/src/llvm-project/clang/test/CodeGenCXX/2004-11-27-ExceptionCleanupAssertion.cpp
new file mode 100644
index 0000000..ebcce77
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2004-11-27-ExceptionCleanupAssertion.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 %s -emit-llvm -o /dev/null
+
+// This is PR421
+
+struct Strongbad {
+ Strongbad(const char *str );
+ ~Strongbad();
+ operator const char *() const;
+};
+
+void TheCheat () {
+ Strongbad foo(0);
+ Strongbad dirs[] = { Strongbad(0) + 1};
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2004-11-27-FriendDefaultArgCrash.cpp b/src/llvm-project/clang/test/CodeGenCXX/2004-11-27-FriendDefaultArgCrash.cpp
new file mode 100644
index 0000000..c478e7d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2004-11-27-FriendDefaultArgCrash.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -emit-llvm %s -o /dev/null
+
+// PR447
+
+namespace nm {
+ struct str {
+ friend void foo(int arg = 0) {};
+ };
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2005-01-03-StaticInitializers.cpp b/src/llvm-project/clang/test/CodeGenCXX/2005-01-03-StaticInitializers.cpp
new file mode 100644
index 0000000..1c9d120
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2005-01-03-StaticInitializers.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
+// REQUIRES: LP64
+
+struct S {
+ int A[2];
+};
+
+// CHECK-NOT: llvm.global_ctor
+int XX = (int)(long)&(((struct S*)0)->A[1]);
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2005-02-11-AnonymousUnion.cpp b/src/llvm-project/clang/test/CodeGenCXX/2005-02-11-AnonymousUnion.cpp
new file mode 100644
index 0000000..dee5817
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2005-02-11-AnonymousUnion.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 %s -emit-llvm -o -
+
+// Test anonymous union with members of the same size.
+int test1(float F) {
+ union {
+ float G;
+ int i;
+ };
+ G = F;
+ return i;
+}
+
+// test anonymous union with members of differing size.
+int test2(short F) {
+ volatile union {
+ short G;
+ int i;
+ };
+ G = F;
+ return i;
+}
+
+// Make sure that normal unions work. duh :)
+volatile union U_t {
+ short S;
+ int i;
+} U;
+
+int test3(short s) {
+ U.S = s;
+ return U.i;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2005-02-13-BadDynamicInit.cpp b/src/llvm-project/clang/test/CodeGenCXX/2005-02-13-BadDynamicInit.cpp
new file mode 100644
index 0000000..b1db67a
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2005-02-13-BadDynamicInit.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+// This testcase corresponds to PR509
+struct Data {
+ unsigned *data;
+ unsigned array[1];
+};
+
+// CHECK-NOT: llvm.global_ctors
+Data shared_null = { shared_null.array };
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2005-02-19-BitfieldStructCrash.cpp b/src/llvm-project/clang/test/CodeGenCXX/2005-02-19-BitfieldStructCrash.cpp
new file mode 100644
index 0000000..937a300
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2005-02-19-BitfieldStructCrash.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -emit-llvm %s -o -
+
+struct QChar {unsigned short X; QChar(unsigned short); } ;
+
+struct Command {
+ Command(QChar c) : c(c) {}
+ unsigned int type : 4;
+ QChar c;
+ };
+
+Command X(QChar('c'));
+
+void Foo(QChar );
+void bar() { Foo(X.c); }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2005-02-19-UnnamedVirtualThunkArgument.cpp b/src/llvm-project/clang/test/CodeGenCXX/2005-02-19-UnnamedVirtualThunkArgument.cpp
new file mode 100644
index 0000000..986001a
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2005-02-19-UnnamedVirtualThunkArgument.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -emit-llvm %s -o /dev/null
+
+struct Foo {
+ Foo();
+ virtual ~Foo();
+};
+
+struct Bar {
+ Bar();
+ virtual ~Bar();
+ virtual bool test(bool) const;
+};
+
+struct Baz : public Foo, public Bar {
+ Baz();
+ virtual ~Baz();
+ virtual bool test(bool) const;
+};
+
+bool Baz::test(bool) const {
+ return true;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2005-02-20-BrokenReferenceTest.cpp b/src/llvm-project/clang/test/CodeGenCXX/2005-02-20-BrokenReferenceTest.cpp
new file mode 100644
index 0000000..36f911e
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2005-02-20-BrokenReferenceTest.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -emit-llvm %s -o /dev/null
+
+void test(unsigned char *b, int rb) {
+ typedef unsigned char imgfoo[10][rb];
+ imgfoo &br = *(imgfoo *)b;
+
+ br[0][0] = 1;
+
+ rb = br[0][0];
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2006-03-01-GimplifyCrash.cpp b/src/llvm-project/clang/test/CodeGenCXX/2006-03-01-GimplifyCrash.cpp
new file mode 100644
index 0000000..b809751
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2006-03-01-GimplifyCrash.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -emit-llvm %s -o -
+
+struct PrefMapElem {
+ virtual ~PrefMapElem();
+ unsigned int fPrefId;
+};
+
+int foo() {
+ PrefMapElem* fMap;
+ if (fMap[0].fPrefId == 1)
+ return 1;
+
+ return 0;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2006-03-06-C++RecurseCrash.cpp b/src/llvm-project/clang/test/CodeGenCXX/2006-03-06-C++RecurseCrash.cpp
new file mode 100644
index 0000000..01476b7
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2006-03-06-C++RecurseCrash.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -emit-llvm %s -o -
+namespace std {
+ class exception { };
+
+ class type_info {
+ public:
+ virtual ~type_info();
+ };
+
+}
+
+namespace __cxxabiv1 {
+ class __si_class_type_info : public std::type_info {
+ ~__si_class_type_info();
+ };
+}
+
+class recursive_init: public std::exception {
+public:
+ virtual ~recursive_init() throw ();
+};
+
+recursive_init::~recursive_init() throw() { }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2006-09-12-OpaqueStructCrash.cpp b/src/llvm-project/clang/test/CodeGenCXX/2006-09-12-OpaqueStructCrash.cpp
new file mode 100644
index 0000000..c5a2d5a
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2006-09-12-OpaqueStructCrash.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - %s
+// RUN: %clang_cc1 -triple %ms_abi_triple -fno-rtti -emit-llvm -o - %s
+
+struct A {
+ virtual ~A();
+};
+
+template <typename Ty>
+struct B : public A {
+ ~B () { delete [] val; }
+private:
+ Ty* val;
+};
+
+template <typename Ty>
+struct C : public A {
+ C ();
+ ~C ();
+};
+
+template <typename Ty>
+struct D : public A {
+ D () {}
+ private:
+ B<C<Ty> > blocks;
+};
+
+template class D<double>;
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2006-10-30-ClassBitfield.cpp b/src/llvm-project/clang/test/CodeGenCXX/2006-10-30-ClassBitfield.cpp
new file mode 100644
index 0000000..8f61f7b
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2006-10-30-ClassBitfield.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -emit-llvm %s -o -
+// PR954
+
+struct _Refcount_Base {
+ unsigned long _M_ref_count;
+ int _M_ref_count_lock;
+ _Refcount_Base() : _M_ref_count(0) {}
+};
+
+struct _Rope_RopeRep : public _Refcount_Base
+{
+public:
+ int _M_tag:8;
+};
+
+int foo(_Rope_RopeRep* r) { return r->_M_tag; }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2006-11-20-GlobalSymbols.cpp b/src/llvm-project/clang/test/CodeGenCXX/2006-11-20-GlobalSymbols.cpp
new file mode 100644
index 0000000..74a7fb6
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2006-11-20-GlobalSymbols.cpp
@@ -0,0 +1,11 @@
+// PR1013
+// Check to make sure debug symbols use the correct name for globals and
+// functions. Will not assemble if it fails to.
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -o - %s | FileCheck %s
+
+// CHECK: f\01oo"
+int foo __asm__("f\001oo");
+
+int bar() {
+ return foo;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2006-11-30-ConstantExprCrash.cpp b/src/llvm-project/clang/test/CodeGenCXX/2006-11-30-ConstantExprCrash.cpp
new file mode 100644
index 0000000..2088e63
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2006-11-30-ConstantExprCrash.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 %s -emit-llvm -o -
+// PR1027
+
+struct sys_var {
+ unsigned name_length;
+
+ bool no_support_one_shot;
+ sys_var() {}
+};
+
+
+struct sys_var_thd : public sys_var {
+};
+
+extern sys_var_thd sys_auto_is_null;
+
+sys_var *getsys_variables() {
+ return &sys_auto_is_null;
+}
+
+sys_var *sys_variables = &sys_auto_is_null;
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2007-01-02-UnboundedArray.cpp b/src/llvm-project/clang/test/CodeGenCXX/2007-01-02-UnboundedArray.cpp
new file mode 100644
index 0000000..c76b7ef
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2007-01-02-UnboundedArray.cpp
@@ -0,0 +1,14 @@
+// Make sure unbounded arrays compile with debug information.
+//
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited %s -o -
+
+// PR1068
+
+struct Object {
+ char buffer[];
+};
+
+int main(int argc, char** argv) {
+ new Object;
+ return 0;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2007-01-06-PtrMethodInit.cpp b/src/llvm-project/clang/test/CodeGenCXX/2007-01-06-PtrMethodInit.cpp
new file mode 100644
index 0000000..37005c5
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2007-01-06-PtrMethodInit.cpp
@@ -0,0 +1,75 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple i386-apple-macosx10.7.2
+// PR1084
+
+extern "C"
+{
+ typedef unsigned char PRUint8;
+ typedef unsigned int PRUint32;
+}
+typedef PRUint32 nsresult;
+struct nsID
+{
+};
+typedef nsID nsIID;
+class nsISupports
+{
+};
+extern "C++"
+{
+ template < class T > struct nsCOMTypeInfo
+ {
+ static const nsIID & GetIID ()
+ {
+ }
+ };
+}
+
+class nsIDOMEvent:public nsISupports
+{
+};
+class nsIDOMEventListener:public nsISupports
+{
+public:static const nsIID & GetIID ()
+ {
+ }
+ virtual nsresult
+ __attribute__ ((regparm (0), cdecl)) HandleEvent (nsIDOMEvent * event) =
+ 0;
+};
+class nsIDOMMouseListener:public nsIDOMEventListener
+{
+public:static const nsIID & GetIID ()
+ {
+ static const nsIID iid = {
+ };
+ }
+ virtual nsresult
+ __attribute__ ((regparm (0),
+ cdecl)) MouseDown (nsIDOMEvent * aMouseEvent) = 0;
+};
+typedef
+typeof (&nsIDOMEventListener::HandleEvent)
+ GenericHandler;
+ struct EventDispatchData
+ {
+ PRUint32 message;
+ GenericHandler method;
+ PRUint8 bits;
+ };
+ struct EventTypeData
+ {
+ const EventDispatchData *events;
+ int numEvents;
+ const nsIID *iid;
+ };
+ static const EventDispatchData sMouseEvents[] = {
+ {
+ (300 + 2),
+ reinterpret_cast < GenericHandler > (&nsIDOMMouseListener::MouseDown),
+ 0x01}
+ };
+static const EventTypeData sEventTypes[] = {
+ {
+ sMouseEvents, (sizeof (sMouseEvents) / sizeof (sMouseEvents[0])),
+ &nsCOMTypeInfo < nsIDOMMouseListener >::GetIID ()}
+};
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2007-04-05-PackedBitFields-1.cpp b/src/llvm-project/clang/test/CodeGenCXX/2007-04-05-PackedBitFields-1.cpp
new file mode 100644
index 0000000..6c39b55
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2007-04-05-PackedBitFields-1.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -emit-llvm %s -o -
+
+#ifdef PACKED
+#define P __attribute__((packed))
+#else
+#define P
+#endif
+
+struct P M_Packed {
+ unsigned int l_Packed;
+ unsigned short k_Packed : 6,
+ i_Packed : 15,
+ j_Packed : 11;
+
+};
+
+struct M_Packed sM_Packed;
+
+int testM_Packed (void) {
+ struct M_Packed x;
+ return (x.i_Packed != 0);
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2007-04-05-PackedBitFieldsOverlap-2.cpp b/src/llvm-project/clang/test/CodeGenCXX/2007-04-05-PackedBitFieldsOverlap-2.cpp
new file mode 100644
index 0000000..d7b0eae
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2007-04-05-PackedBitFieldsOverlap-2.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -emit-llvm %s -o -
+
+#ifdef PACKED
+#define P __attribute__((packed))
+#else
+#define P
+#endif
+
+struct P M_Packed {
+ unsigned long sorted : 1;
+ unsigned long from_array : 1;
+ unsigned long mixed_encoding : 1;
+ unsigned long encoding : 8;
+ unsigned long count : 21;
+
+};
+
+struct M_Packed sM_Packed;
+
+int testM_Packed (void) {
+ struct M_Packed x;
+ return (x.count != 0);
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2007-04-05-PackedBitFieldsOverlap.cpp b/src/llvm-project/clang/test/CodeGenCXX/2007-04-05-PackedBitFieldsOverlap.cpp
new file mode 100644
index 0000000..6911767
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2007-04-05-PackedBitFieldsOverlap.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -emit-llvm %s -o -
+
+
+#ifdef PACKED
+#define P __attribute__((packed))
+#else
+#define P
+#endif
+
+struct P M_Packed {
+ unsigned int l_Packed;
+ unsigned short k_Packed : 6,
+ i_Packed : 15;
+ char c;
+
+};
+
+struct M_Packed sM_Packed;
+
+int testM_Packed (void) {
+ struct M_Packed x;
+ return (x.i_Packed != 0);
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2007-04-05-PackedBitFieldsSmall.cpp b/src/llvm-project/clang/test/CodeGenCXX/2007-04-05-PackedBitFieldsSmall.cpp
new file mode 100644
index 0000000..b31f95f
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2007-04-05-PackedBitFieldsSmall.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -emit-llvm %s -o -
+
+
+#ifdef PACKED
+// This is an example where size of Packed struct is smaller then
+// the size of bit field type.
+#define P __attribute__((packed))
+#else
+#define P
+#endif
+
+struct P M_Packed {
+ unsigned long long X:50;
+ unsigned Y:2;
+};
+
+struct M_Packed sM_Packed;
+
+int testM_Packed (void) {
+ struct M_Packed x;
+ return (0 != x.Y);
+}
+
+int testM_Packed2 (void) {
+ struct M_Packed x;
+ return (0 != x.X);
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2007-04-05-StructPackedFieldUnpacked.cpp b/src/llvm-project/clang/test/CodeGenCXX/2007-04-05-StructPackedFieldUnpacked.cpp
new file mode 100644
index 0000000..c848e7c
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2007-04-05-StructPackedFieldUnpacked.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -emit-llvm %s -o -
+
+#ifdef PACKED
+#define P __attribute__((packed))
+#else
+#define P
+#endif
+
+struct UnPacked {
+ int X;
+ int Y;
+};
+
+struct P M_Packed {
+ unsigned char A;
+ struct UnPacked B;
+};
+
+struct M_Packed sM_Packed;
+
+int testM_Packed (void) {
+ struct M_Packed x;
+ return (x.B.Y != 0);
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2007-04-10-PackedUnion.cpp b/src/llvm-project/clang/test/CodeGenCXX/2007-04-10-PackedUnion.cpp
new file mode 100644
index 0000000..863fc82
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2007-04-10-PackedUnion.cpp
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -emit-llvm %s -o /dev/null
+extern "C" {
+
+#pragma pack(push, 2)
+ typedef struct ABC* abc;
+
+ struct ABCS {
+ float red;
+ float green;
+ float blue;
+ float alpha;
+ };
+
+ typedef void (*XYZ)();
+#pragma pack(pop)
+}
+
+
+union ABCU {
+ ABCS color;
+ XYZ bg;
+};
+
+struct AData {
+ ABCU data;
+};
+
+class L {
+ public:
+ L() {}
+ L(const L& other);
+
+ private:
+ AData fdata;
+};
+
+
+L::L(const L& other)
+{
+ fdata = other.fdata;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2007-04-14-FNoBuiltin.cpp b/src/llvm-project/clang/test/CodeGenCXX/2007-04-14-FNoBuiltin.cpp
new file mode 100644
index 0000000..4475fda
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2007-04-14-FNoBuiltin.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -emit-llvm %s -fno-builtin -o - | FileCheck %s
+// Check that -fno-builtin is honored.
+
+extern "C" int printf(const char*, ...);
+void foo(const char *msg) {
+ // CHECK: call{{.*}}printf
+ printf("%s\n",msg);
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2007-05-03-VectorInit.cpp b/src/llvm-project/clang/test/CodeGenCXX/2007-05-03-VectorInit.cpp
new file mode 100644
index 0000000..b22b52a
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2007-05-03-VectorInit.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -emit-llvm %s -o -
+// PR1378
+
+typedef float v4sf __attribute__((vector_size(16)));
+
+typedef v4sf float4;
+
+static float4 splat4(float a)
+{
+ float4 tmp = {a,a,a,a};
+ return tmp;
+}
+
+float4 foo(float a)
+{
+ return splat4(a);
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2007-07-29-RestrictPtrArg.cpp b/src/llvm-project/clang/test/CodeGenCXX/2007-07-29-RestrictPtrArg.cpp
new file mode 100644
index 0000000..d7c96f5
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2007-07-29-RestrictPtrArg.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
+
+void foo(int * __restrict myptr1, int * myptr2) {
+ // CHECK: noalias
+ myptr1[0] = 0;
+ myptr2[0] = 0;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2007-07-29-RestrictRefArg.cpp b/src/llvm-project/clang/test/CodeGenCXX/2007-07-29-RestrictRefArg.cpp
new file mode 100644
index 0000000..aa9f48b
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2007-07-29-RestrictRefArg.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
+
+void foo(int & __restrict myptr1, int & myptr2) {
+ // CHECK: noalias
+ myptr1 = 0;
+ myptr2 = 0;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2007-09-10-RecursiveTypeResolution.cpp b/src/llvm-project/clang/test/CodeGenCXX/2007-09-10-RecursiveTypeResolution.cpp
new file mode 100644
index 0000000..ec8a516
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2007-09-10-RecursiveTypeResolution.cpp
@@ -0,0 +1,87 @@
+// RUN: %clang_cc1 -emit-llvm %s -o -
+// PR1634
+
+namespace Manta
+{
+ class CallbackHandle
+ {
+ protected:virtual ~ CallbackHandle (void)
+ {
+ }
+ };
+template < typename Data1 > class CallbackBase_1Data:public CallbackHandle
+ {
+ };
+}
+
+namespace __gnu_cxx
+{
+ template < typename _Iterator, typename _Container >
+ class __normal_iterator
+ {
+ _Iterator _M_current;
+ };
+}
+
+namespace std
+{
+ template < typename _Tp > struct allocator
+ {
+ typedef _Tp *pointer;
+ };
+ template < typename _InputIterator,
+ typename _Tp > inline void find (_InputIterator __last,
+ const _Tp & __val)
+ {
+ };
+}
+
+namespace Manta
+{
+ template < typename _Tp, typename _Alloc> struct _Vector_base
+ {
+ struct _Vector_impl
+ {
+ _Tp *_M_start;
+ };
+ public:
+ _Vector_impl _M_impl;
+ };
+ template < typename _Tp, typename _Alloc = std::allocator < _Tp > >
+ class vector:protected _Vector_base < _Tp,_Alloc >
+ {
+ public:
+ typedef __gnu_cxx::__normal_iterator < typename _Alloc::pointer,
+ vector < _Tp, _Alloc > > iterator;
+ iterator end ()
+ {
+ }
+ };
+ class MantaInterface
+ {
+ };
+ class RTRT
+ {
+ virtual CallbackHandle *registerTerminationCallback (CallbackBase_1Data <
+ MantaInterface * >*);
+ virtual void unregisterCallback (CallbackHandle *);
+ typedef vector < CallbackBase_1Data < int >*>PRCallbackMapType;
+ PRCallbackMapType parallelPreRenderCallbacks;
+ };
+}
+using namespace Manta;
+CallbackHandle *
+RTRT::registerTerminationCallback (CallbackBase_1Data < MantaInterface * >*cb)
+{
+ return cb;
+}
+
+void
+RTRT::unregisterCallback (CallbackHandle * callback)
+{
+ {
+ typedef CallbackBase_1Data < int > callback_t;
+ callback_t *cb = static_cast < callback_t * >(callback);
+ find (parallelPreRenderCallbacks.end (), cb);
+ }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2007-10-01-StructResize.cpp b/src/llvm-project/clang/test/CodeGenCXX/2007-10-01-StructResize.cpp
new file mode 100644
index 0000000..8e5750d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2007-10-01-StructResize.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -emit-llvm %s -o /dev/null
+
+#pragma pack(4)
+
+struct Bork {
+ unsigned int f1 : 3;
+ unsigned int f2 : 30;
+};
+
+int Foo(Bork *hdr) {
+ hdr->f1 = 7;
+ hdr->f2 = 927;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2008-01-12-VecInit.cpp b/src/llvm-project/clang/test/CodeGenCXX/2008-01-12-VecInit.cpp
new file mode 100644
index 0000000..92bfd51
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2008-01-12-VecInit.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -emit-llvm %s -o -
+// rdar://5685492
+
+typedef int __attribute__((vector_size(16))) v;
+v vt = {1, 2, 3, 4};
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2008-05-07-CrazyOffsetOf.cpp b/src/llvm-project/clang/test/CodeGenCXX/2008-05-07-CrazyOffsetOf.cpp
new file mode 100644
index 0000000..f842f95
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2008-05-07-CrazyOffsetOf.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -emit-llvm %s -o -
+// rdar://5914926
+
+struct bork {
+ struct bork *next_local;
+ char * query;
+};
+int offset = (char *) &(((struct bork *) 0x10)->query) - (char *) 0x10;
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2009-03-17-dbg.cpp b/src/llvm-project/clang/test/CodeGenCXX/2009-03-17-dbg.cpp
new file mode 100644
index 0000000..22d9059
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2009-03-17-dbg.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -emit-llvm %s -o /dev/null -debug-info-kind=limited
+
+template <typename T1,typename T2>
+inline void f(const T1&,const T2&) { }
+
+template <typename T1,typename T2,void F(const T1&,const T2&)>
+struct A {
+ template <typename T> void g(T& i) { }
+};
+
+int main() {
+ int i;
+ A<int,int,f> a;
+ a.g(i);
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2009-04-23-bool2.cpp b/src/llvm-project/clang/test/CodeGenCXX/2009-04-23-bool2.cpp
new file mode 100644
index 0000000..33c2c02
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2009-04-23-bool2.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm %s -o /dev/null
+// g++.old-deja/g++.jason/bool2.C from gcc testsuite.
+// Crashed before 67975 went in.
+struct F {
+ bool b1 : 1;
+ bool b2 : 7;
+};
+
+int main()
+{
+ F f = { true, true };
+
+ if (int (f.b1) != 1)
+ return 1;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2009-05-04-PureConstNounwind.cpp b/src/llvm-project/clang/test/CodeGenCXX/2009-05-04-PureConstNounwind.cpp
new file mode 100644
index 0000000..dd5fa3e
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2009-05-04-PureConstNounwind.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -fexceptions -emit-llvm %s -o - | FileCheck %s
+int c(void) __attribute__((const));
+int p(void) __attribute__((pure));
+int t(void);
+
+// CHECK: define i32 @_Z1fv() [[TF:#[0-9]+]] {
+int f(void) {
+ // CHECK: call i32 @_Z1cv() [[NUW_RN_CALL:#[0-9]+]]
+ // CHECK: call i32 @_Z1pv() [[NUW_RO_CALL:#[0-9]+]]
+ return c() + p() + t();
+}
+
+// CHECK: declare i32 @_Z1cv() [[NUW_RN:#[0-9]+]]
+// CHECK: declare i32 @_Z1pv() [[NUW_RO:#[0-9]+]]
+// CHECK: declare i32 @_Z1tv() [[TF2:#[0-9]+]]
+
+// CHECK: attributes [[TF]] = { {{.*}} }
+// CHECK: attributes [[NUW_RN]] = { nounwind readnone{{.*}} }
+// CHECK: attributes [[NUW_RO]] = { nounwind readonly{{.*}} }
+// CHECK: attributes [[TF2]] = { {{.*}} }
+// CHECK: attributes [[NUW_RN_CALL]] = { nounwind readnone }
+// CHECK: attributes [[NUW_RO_CALL]] = { nounwind readonly }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2009-06-16-DebugInfoCrash.cpp b/src/llvm-project/clang/test/CodeGenCXX/2009-06-16-DebugInfoCrash.cpp
new file mode 100644
index 0000000..870e15c
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2009-06-16-DebugInfoCrash.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -emit-llvm %s -o /dev/null -debug-info-kind=limited
+// This crashes if we try to emit debug info for TEMPLATE_DECL members.
+template <class T> class K2PtrVectorBase {};
+template <class T> class K2Vector {};
+template <class U > class K2Vector<U*> : public K2PtrVectorBase<U*> {};
+class ScriptInfoManager {
+ void PostRegister() ;
+ template <class SI> short ReplaceExistingElement(K2Vector<SI*>& v);
+};
+void ScriptInfoManager::PostRegister() {}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2009-07-16-Using.cpp b/src/llvm-project/clang/test/CodeGenCXX/2009-07-16-Using.cpp
new file mode 100644
index 0000000..a692d4d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2009-07-16-Using.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -emit-llvm %s -o /dev/null
+
+namespace A {
+ typedef int B;
+}
+struct B {
+};
+using ::A::B;
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2009-08-05-ZeroInitWidth.cpp b/src/llvm-project/clang/test/CodeGenCXX/2009-08-05-ZeroInitWidth.cpp
new file mode 100644
index 0000000..4404d4a
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2009-08-05-ZeroInitWidth.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -emit-llvm %s -o -
+// rdar://7114564
+struct A {
+ unsigned long long : (sizeof(unsigned long long) * 8) - 16;
+};
+struct B {
+ A a;
+};
+struct B b = {
+ {}
+};
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2009-08-11-VectorRetTy.cpp b/src/llvm-project/clang/test/CodeGenCXX/2009-08-11-VectorRetTy.cpp
new file mode 100644
index 0000000..21b88c9
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2009-08-11-VectorRetTy.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 %s -emit-llvm -o /dev/null
+// <rdar://problem/7096460>
+typedef void (*Func) ();
+typedef long long m64 __attribute__((__vector_size__(8), __may_alias__));
+static inline m64 __attribute__((__always_inline__, __nodebug__)) _mm_set1_pi16() {}
+template <class MM>
+static void Bork() {
+ const m64 mmx_0x00ff = _mm_set1_pi16();
+}
+struct A {};
+Func arr[] = {
+ Bork<A>
+};
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2009-09-09-packed-layout.cpp b/src/llvm-project/clang/test/CodeGenCXX/2009-09-09-packed-layout.cpp
new file mode 100644
index 0000000..9de2f61
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2009-09-09-packed-layout.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -emit-llvm -triple i386-apple-darwin11 %s -o /dev/null
+class X {
+ public:
+ virtual ~X();
+ short y;
+};
+#pragma pack(push, 1)
+class Z : public X {
+ public: enum { foo = ('x') };
+ virtual int y() const;
+};
+#pragma pack(pop)
+class Y : public X {
+public: enum { foo = ('y'), bar = 0 };
+};
+X x;
+Y y;
+Z z;
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2009-10-27-crash.cpp b/src/llvm-project/clang/test/CodeGenCXX/2009-10-27-crash.cpp
new file mode 100644
index 0000000..482bb75
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2009-10-27-crash.cpp
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -emit-llvm %s -o /dev/null
+// Radar 7328944
+
+typedef struct
+{
+ unsigned short a : 1;
+ unsigned short b : 2;
+ unsigned short c : 1;
+ unsigned short d : 1;
+ unsigned short e : 1;
+ unsigned short f : 1;
+ unsigned short g : 2;
+ unsigned short : 7;
+ union
+ {
+ struct
+ {
+ unsigned char h : 1;
+ unsigned char i : 1;
+ unsigned char j : 1;
+ unsigned char : 5;
+ };
+ struct
+ {
+ unsigned char k : 3;
+ unsigned char : 5;
+ };
+ };
+ unsigned char : 8;
+} tt;
+
+typedef struct
+{
+ unsigned char s;
+ tt t;
+ unsigned int u;
+} ttt;
+
+ttt X = {
+ 4,
+ { 0 },
+ 55,
+};
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2009-12-23-MissingSext.cpp b/src/llvm-project/clang/test/CodeGenCXX/2009-12-23-MissingSext.cpp
new file mode 100644
index 0000000..bff6ac7
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2009-12-23-MissingSext.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 %s -triple x86_64-unknown-unknown -emit-llvm -o - | FileCheck %s
+// The store of p.y into the temporary was not
+// getting extended to 32 bits, so uninitialized
+// bits of the temporary were used. 7366161.
+struct foo {
+ char x:8;
+ signed int y:24;
+};
+int bar(struct foo p, int x) {
+// CHECK: bar
+// CHECK: %[[val:.*]] = load i32, i32* {{.*}}
+// CHECK-NEXT: ashr i32 %[[val]]
+// CHECK: = load i32, i32* {{.*}}
+// CHECK: = load i32, i32* {{.*}}
+// CHECK: %[[val:.*]] = load i32, i32* {{.*}}
+// CHECK-NEXT: ashr i32 %[[val]]
+ x = (p.y > x ? x : p.y);
+ return x;
+// CHECK: ret
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2010-03-09-AnonAggregate.cpp b/src/llvm-project/clang/test/CodeGenCXX/2010-03-09-AnonAggregate.cpp
new file mode 100644
index 0000000..056b500
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2010-03-09-AnonAggregate.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -debug-info-kind=limited -S -o %t %s
+// PR: 6554
+// More then one anonymous aggregates on one line creates chaos when MDNode uniquness is
+// combined with RAUW operation.
+// This test case causes crashes if malloc is configured to trip buffer overruns.
+class MO {
+
+ union { struct { union { int BA; } Val; int Offset; } OffsetedInfo; } Contents;
+
+};
+
+class MO m;
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2010-05-10-Var-DbgInfo.cpp b/src/llvm-project/clang/test/CodeGenCXX/2010-05-10-Var-DbgInfo.cpp
new file mode 100644
index 0000000..2b39e7d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2010-05-10-Var-DbgInfo.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited %s -o /dev/null
+// PR 7104
+
+struct A {
+ int Ai;
+};
+
+struct B : public A {};
+struct C : public B {};
+
+const char * f(int C::*){ return ""; }
+int f(int B::*) { return 1; }
+
+struct D : public C {};
+
+const char * g(int B::*){ return ""; }
+int g(int D::*) { return 1; }
+
+void test()
+{
+ int i = f(&A::Ai);
+
+ const char * str = g(&A::Ai);
+}
+
+// conversion of B::* to C::* is better than conversion of A::* to C::*
+typedef void (A::*pmfa)();
+typedef void (B::*pmfb)();
+typedef void (C::*pmfc)();
+
+struct X {
+ operator pmfa();
+ operator pmfb();
+};
+
+
+void g(pmfc);
+
+void test2(X x)
+{
+ g(x);
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2010-05-11-alwaysinlineinstantiation.cpp b/src/llvm-project/clang/test/CodeGenCXX/2010-05-11-alwaysinlineinstantiation.cpp
new file mode 100644
index 0000000..bf00c0f
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2010-05-11-alwaysinlineinstantiation.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple %s -o - | FileCheck %s
+
+// CHECK-NOT: ZN12basic_stringIcEC1Ev
+// CHECK: ZN12basic_stringIcED1Ev
+// CHECK: ZN12basic_stringIcED1Ev
+template<class charT>
+class basic_string
+{
+public:
+ basic_string();
+ ~basic_string();
+};
+
+template <class charT>
+__attribute__ ((__visibility__("hidden"), __always_inline__)) inline
+basic_string<charT>::basic_string()
+{
+}
+
+template <class charT>
+inline
+basic_string<charT>::~basic_string()
+{
+}
+
+typedef basic_string<char> string;
+
+extern template class basic_string<char>;
+
+int main()
+{
+ string s;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2010-05-12-PtrToMember-Dbg.cpp b/src/llvm-project/clang/test/CodeGenCXX/2010-05-12-PtrToMember-Dbg.cpp
new file mode 100644
index 0000000..355c3c9
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2010-05-12-PtrToMember-Dbg.cpp
@@ -0,0 +1,17 @@
+//RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -o - %s | FileCheck %s
+//CHECK: DILocalVariable(
+class Foo
+{
+ public:
+ int x;
+ int y;
+ Foo (int i, int j) { x = i; y = j; }
+};
+
+
+Foo foo(10, 11);
+
+int main() {
+ int Foo::* pmi = &Foo::y;
+ return foo.*pmi;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2010-06-21-LocalVarDbg.cpp b/src/llvm-project/clang/test/CodeGenCXX/2010-06-21-LocalVarDbg.cpp
new file mode 100644
index 0000000..c0c8bf6
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2010-06-21-LocalVarDbg.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -debug-info-kind=limited -emit-llvm %s -o - | FileCheck %s
+// Do not use function name to create named metadata used to hold
+// local variable info. For example. llvm.dbg.lv.~A is an invalid name.
+
+// CHECK-NOT: llvm.dbg.lv.~A
+class A {
+public:
+ ~A() { int i = 0; i++; }
+};
+
+int foo(int i) {
+ A a;
+ return 0;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2010-06-22-BitfieldInit.cpp b/src/llvm-project/clang/test/CodeGenCXX/2010-06-22-BitfieldInit.cpp
new file mode 100644
index 0000000..ae02cd9
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2010-06-22-BitfieldInit.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited %s -o -
+struct TEST2
+{
+ int subid:32;
+ int :0;
+};
+
+typedef struct _TEST3
+{
+ TEST2 foo;
+ TEST2 foo2;
+} TEST3;
+
+TEST3 test =
+ {
+ {0},
+ {0}
+ };
+
+int main() { return 0; }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2010-06-22-ZeroBitfield.cpp b/src/llvm-project/clang/test/CodeGenCXX/2010-06-22-ZeroBitfield.cpp
new file mode 100644
index 0000000..0f600e7
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2010-06-22-ZeroBitfield.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited %s -o -
+struct s8_0 { unsigned : 0; };
+struct s8_1 { double x; };
+struct s8 { s8_0 a; s8_1 b; };
+s8 f8() { return s8(); }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2010-07-23-DeclLoc.cpp b/src/llvm-project/clang/test/CodeGenCXX/2010-07-23-DeclLoc.cpp
new file mode 100644
index 0000000..a88d605
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2010-07-23-DeclLoc.cpp
@@ -0,0 +1,87 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited %s -o - | FileCheck %s
+// Require the template function declaration refer to the correct filename.
+// First, locate the function decl in metadata, and pluck out the file handle:
+// CHECK: !DISubprogram(name: "extract_dwarf_data_from_header
+// CHECK-SAME: file: [[FILE:![0-9]+]]
+// Second: Require that filehandle refer to the correct filename:
+// CHECK: [[FILE]] = !DIFile(filename: "decl_should_be_here.hpp"
+typedef long unsigned int __darwin_size_t;
+typedef __darwin_size_t size_t;
+typedef unsigned char uint8_t;
+typedef unsigned int uint32_t;
+typedef unsigned long long uint64_t;
+namespace std {
+ template<typename _Tp> class auto_ptr {
+ _Tp* _M_ptr;
+ public:
+ typedef _Tp element_type;
+ auto_ptr(element_type* __p = 0) throw() : _M_ptr(__p) { }
+ element_type& operator*() const throw() { }
+ };
+}
+class Pointer32 {
+public:
+ typedef uint32_t ptr_t;
+ typedef uint32_t size_t;
+};
+class Pointer64 {
+public:
+ typedef uint64_t ptr_t;
+ typedef uint64_t size_t;
+};
+class BigEndian {};
+class LittleEndian {};
+template <typename _SIZE, typename _ENDIANNESS> class SizeAndEndianness {
+public:
+ typedef _SIZE SIZE;
+};
+typedef SizeAndEndianness<Pointer32, LittleEndian> ISA32Little;
+typedef SizeAndEndianness<Pointer32, BigEndian> ISA32Big;
+typedef SizeAndEndianness<Pointer64, LittleEndian> ISA64Little;
+typedef SizeAndEndianness<Pointer64, BigEndian> ISA64Big;
+template <typename SIZE> class TRange {
+protected:
+ typename SIZE::ptr_t _location;
+ typename SIZE::size_t _length;
+ TRange(typename SIZE::ptr_t location, typename SIZE::size_t length) : _location(location), _length(length) { }
+};
+template <typename SIZE, typename T> class TRangeValue : public TRange<SIZE> {
+ T _value;
+public:
+ TRangeValue(typename SIZE::ptr_t location, typename SIZE::size_t length, T value) : TRange<SIZE>(location, length), _value(value) {};
+};
+template <typename SIZE> class TAddressRelocator {};
+class CSCppSymbolOwner{};
+class CSCppSymbolOwnerData{};
+template <typename SIZE> class TRawSymbolOwnerData
+{
+ TRangeValue< SIZE, uint8_t* > _TEXT_text_section;
+ const char* _dsym_path;
+ uint32_t _dylib_current_version;
+ uint32_t _dylib_compatibility_version;
+public:
+ TRawSymbolOwnerData() :
+ _TEXT_text_section(0, 0, __null), _dsym_path(__null), _dylib_current_version(0), _dylib_compatibility_version(0) {}
+};
+template <typename SIZE_AND_ENDIANNESS> class TExtendedMachOHeader {};
+# 16 "decl_should_be_here.hpp"
+template <typename SIZE_AND_ENDIANNESS> void extract_dwarf_data_from_header(TExtendedMachOHeader<SIZE_AND_ENDIANNESS>& header,
+ TRawSymbolOwnerData<typename SIZE_AND_ENDIANNESS::SIZE>& symbol_owner_data,
+ TAddressRelocator<typename SIZE_AND_ENDIANNESS::SIZE>* address_relocator) {}
+struct CSCppSymbolOwnerHashFunctor {
+ size_t operator()(const CSCppSymbolOwner& symbol_owner) const {
+# 97 "wrong_place_for_decl.cpp"
+ }
+};
+template <typename SIZE_AND_ENDIANNESS> CSCppSymbolOwnerData* create_symbol_owner_data_arch_specific(CSCppSymbolOwner* symbol_owner, const char* dsym_path) {
+ typedef typename SIZE_AND_ENDIANNESS::SIZE SIZE;
+ std::auto_ptr< TRawSymbolOwnerData<SIZE> > data(new TRawSymbolOwnerData<SIZE>());
+ std::auto_ptr< TExtendedMachOHeader<SIZE_AND_ENDIANNESS> > header;
+ extract_dwarf_data_from_header(*header, *data, (TAddressRelocator<typename SIZE_AND_ENDIANNESS::SIZE>*)__null);
+}
+CSCppSymbolOwnerData* create_symbol_owner_data2(CSCppSymbolOwner* symbol_owner, const char* dsym_path) {
+ create_symbol_owner_data_arch_specific< ISA32Little >(symbol_owner, dsym_path);
+ create_symbol_owner_data_arch_specific< ISA32Big >(symbol_owner, dsym_path);
+ create_symbol_owner_data_arch_specific< ISA64Little >(symbol_owner, dsym_path);
+ create_symbol_owner_data_arch_specific< ISA64Big >(symbol_owner, dsym_path);
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2011-12-19-init-list-ctor.cpp b/src/llvm-project/clang/test/CodeGenCXX/2011-12-19-init-list-ctor.cpp
new file mode 100644
index 0000000..84c4619
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2011-12-19-init-list-ctor.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple x86_64-linux-gnu | FileCheck %s
+
+struct A {
+ A(const char *);
+};
+
+// CHECK: @arr = global [3 x %struct.S] zeroinitializer
+// CHECK: @.str = {{.*}}constant [6 x i8] c"hello\00"
+// CHECK: @.str.1 = {{.*}}constant [6 x i8] c"world\00"
+// CHECK: @.str.2 = {{.*}}constant [8 x i8] c"goodbye\00"
+
+struct S {
+ int n;
+ A s;
+} arr[] = {
+ { 0, "hello" },
+ { 1, "world" },
+ { 2, "goodbye" }
+};
+
+// CHECK: store i32 0, i32* getelementptr inbounds ([3 x %struct.S], [3 x %struct.S]* @arr, i64 0, i64 0, i32 0)
+// CHECK: call void @_ZN1AC1EPKc(%struct.A* getelementptr inbounds ([3 x %struct.S], [3 x %struct.S]* @arr, i64 0, i64 0, i32 1), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i32 0, i32 0))
+// CHECK: store i32 1, i32* getelementptr inbounds ([3 x %struct.S], [3 x %struct.S]* @arr, i64 0, i64 1, i32 0)
+// CHECK: call void @_ZN1AC1EPKc(%struct.A* getelementptr inbounds ([3 x %struct.S], [3 x %struct.S]* @arr, i64 0, i64 1, i32 1), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0))
+// CHECK: store i32 2, i32* getelementptr inbounds ([3 x %struct.S], [3 x %struct.S]* @arr, i64 0, i64 2, i32 0)
+// CHECK: call void @_ZN1AC1EPKc(%struct.A* getelementptr inbounds ([3 x %struct.S], [3 x %struct.S]* @arr, i64 0, i64 2, i32 1), i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str.2, i32 0, i32 0))
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2012-02-06-VecInitialization.cpp b/src/llvm-project/clang/test/CodeGenCXX/2012-02-06-VecInitialization.cpp
new file mode 100644
index 0000000..720420e
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2012-02-06-VecInitialization.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -emit-llvm -o - -triple i386-apple-darwin %s | FileCheck %s
+// PR11930
+
+typedef char vec_t __attribute__ ((__ext_vector_type__ (8)));
+void h() {
+// CHECK: store <8 x i8>
+ vec_t v(0);
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/2012-03-16-StoreAlign.cpp b/src/llvm-project/clang/test/CodeGenCXX/2012-03-16-StoreAlign.cpp
new file mode 100644
index 0000000..5f6189e
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/2012-03-16-StoreAlign.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -emit-llvm -o - -triple x86_64-apple-darwin %s | FileCheck %s
+// <rdar://problem/11043589>
+
+struct Length {
+ Length(double v) {
+ m_floatValue = static_cast<float>(v);
+ }
+
+ bool operator==(const Length& o) const {
+ return getFloatValue() == o.getFloatValue();
+ }
+ bool operator!=(const Length& o) const { return !(*this == o); }
+private:
+ float getFloatValue() const {
+ return m_floatValue;
+ }
+ float m_floatValue;
+};
+
+
+struct Foo {
+ static Length inchLength(double inch);
+ static bool getPageSizeFromName(const Length &A) {
+ static const Length legalWidth = inchLength(8.5);
+ if (A != legalWidth) return true;
+ return false;
+ }
+};
+
+// CHECK: @_ZZN3Foo19getPageSizeFromNameERK6LengthE10legalWidth = linkonce_odr global %struct.Length zeroinitializer, align 4
+// CHECK: store float %{{.*}}, float* getelementptr inbounds (%struct.Length, %struct.Length* @_ZZN3Foo19getPageSizeFromNameERK6LengthE10legalWidth, i32 0, i32 0), align 4
+
+bool bar(Length &b) {
+ Foo f;
+ return f.getPageSizeFromName(b);
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/DynArrayInit.cpp b/src/llvm-project/clang/test/CodeGenCXX/DynArrayInit.cpp
new file mode 100644
index 0000000..fb865e3
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/DynArrayInit.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -O3 -emit-llvm -o - %s | FileCheck %s
+// PR7490
+
+// CHECK-LABEL: define signext i8 @_Z2f0v
+// CHECK: ret i8 0
+// CHECK: }
+inline void* operator new[](unsigned long, void* __p) { return __p; }
+static void f0_a(char *a) {
+ new (a) char[4]();
+}
+char f0() {
+ char a[4];
+ f0_a(a);
+ return a[0] + a[1] + a[2] + a[3];
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/Inputs/debug-info-class-limited.cpp b/src/llvm-project/clang/test/CodeGenCXX/Inputs/debug-info-class-limited.cpp
new file mode 100644
index 0000000..34a1cfa
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/Inputs/debug-info-class-limited.cpp
@@ -0,0 +1,52 @@
+
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "PR16214",{{.*}} line: [[@LINE+2]],{{.*}}
+// CHECK-NOT: DIFlagFwdDecl
+struct PR16214 {
+ int i;
+};
+
+typedef PR16214 bar;
+
+bar *a;
+bar b;
+
+namespace PR14467 {
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "foo",{{.*}} line: [[@LINE+2]],{{.*}}
+// CHECK-NOT: DIFlagFwdDecl
+struct foo {
+};
+
+foo *bar(foo *a) {
+ foo *b = new foo(*a);
+ return b;
+}
+}
+
+namespace test1 {
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "foo",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagFwdDecl
+struct foo {
+};
+
+extern int bar(foo *a);
+int baz(foo *a) {
+ return bar(a);
+}
+}
+
+namespace test2 {
+// FIXME: if we were a bit fancier, we could realize that the 'foo' type is only
+// required because of the 'bar' type which is not required at all (or might
+// only be required to be declared)
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "foo",{{.*}} line: [[@LINE+2]],{{.*}}
+// CHECK-NOT: DIFlagFwdDecl
+struct foo {
+};
+
+struct bar {
+ foo f;
+};
+
+void func() {
+ foo *f;
+}
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/Inputs/override-bit-field-layout.layout b/src/llvm-project/clang/test/CodeGenCXX/Inputs/override-bit-field-layout.layout
new file mode 100644
index 0000000..8e67dce
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/Inputs/override-bit-field-layout.layout
@@ -0,0 +1,16 @@
+
+*** Dumping AST Record Layout
+Type: struct S1
+
+Layout: <ASTRecordLayout
+ Size:16
+ Alignment:16
+ FieldOffsets: [0, 11]>
+
+*** Dumping AST Record Layout
+Type: struct S2
+
+Layout: <ASTRecordLayout
+ Size:128
+ Alignment:64
+ FieldOffsets: [64]>
diff --git a/src/llvm-project/clang/test/CodeGenCXX/Inputs/override-layout-nameless-struct-union.layout b/src/llvm-project/clang/test/CodeGenCXX/Inputs/override-layout-nameless-struct-union.layout
new file mode 100644
index 0000000..9eb4d24
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/Inputs/override-layout-nameless-struct-union.layout
@@ -0,0 +1,16 @@
+
+*** Dumping AST Record Layout
+Type: struct S
+
+Layout: <ASTRecordLayout
+ Size:64
+ Alignment:32
+ FieldOffsets: [0, 32, 32]>
+
+*** Dumping AST Record Layout
+Type: union U
+
+Layout: <ASTRecordLayout
+ Size:96
+ Alignment:32
+ FieldOffsets: [0, 0, 32, 64, 68, 73]>
diff --git a/src/llvm-project/clang/test/CodeGenCXX/Inputs/override-layout-packed-base.layout b/src/llvm-project/clang/test/CodeGenCXX/Inputs/override-layout-packed-base.layout
new file mode 100644
index 0000000..2ebcb98
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/Inputs/override-layout-packed-base.layout
@@ -0,0 +1,28 @@
+
+*** Dumping AST Record Layout
+Type: class B<0>
+
+Layout: <ASTRecordLayout
+ Size:40
+ FieldOffsets: [0, 32]>
+
+*** Dumping AST Record Layout
+Type: class B<1>
+
+Layout: <ASTRecordLayout
+ Size:40
+ FieldOffsets: [0, 32]>
+
+*** Dumping AST Record Layout
+Type: class C
+
+Layout: <ASTRecordLayout
+ Size:88
+ FieldOffsets: [80]>
+
+*** Dumping AST Record Layout
+Type: class D
+
+Layout: <ASTRecordLayout
+ Size:120
+ FieldOffsets: [32]>
diff --git a/src/llvm-project/clang/test/CodeGenCXX/Inputs/profile-remap.map b/src/llvm-project/clang/test/CodeGenCXX/Inputs/profile-remap.map
new file mode 100644
index 0000000..50b812a
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/Inputs/profile-remap.map
@@ -0,0 +1,2 @@
+name 3Foo 3Bar
+type N3Foo1XE N3Baz1YE
diff --git a/src/llvm-project/clang/test/CodeGenCXX/Inputs/profile-remap.proftext b/src/llvm-project/clang/test/CodeGenCXX/Inputs/profile-remap.proftext
new file mode 100644
index 0000000..a1f90cf
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/Inputs/profile-remap.proftext
@@ -0,0 +1,7 @@
+:ir
+_ZN3Foo8functionENS_1XE
+29667547796
+2
+10
+90
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/Inputs/profile-remap.samples b/src/llvm-project/clang/test/CodeGenCXX/Inputs/profile-remap.samples
new file mode 100644
index 0000000..45e5994
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/Inputs/profile-remap.samples
@@ -0,0 +1,3 @@
+_ZN3Bar8functionEN3Baz1YE:100:0
+ 2: 10
+ 4: 90
diff --git a/src/llvm-project/clang/test/CodeGenCXX/Inputs/std-compare.h b/src/llvm-project/clang/test/CodeGenCXX/Inputs/std-compare.h
new file mode 100644
index 0000000..a6ab605
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/Inputs/std-compare.h
@@ -0,0 +1,437 @@
+#ifndef STD_COMPARE_H
+#define STD_COMPARE_H
+
+namespace std {
+inline namespace __1 {
+
+// exposition only
+enum class _EqResult : unsigned char {
+ __zero = 0,
+ __equal = __zero,
+ __equiv = __equal,
+ __nonequal = 1,
+ __nonequiv = __nonequal
+};
+
+enum class _OrdResult : signed char {
+ __less = -1,
+ __greater = 1
+};
+
+enum class _NCmpResult : signed char {
+ __unordered = -127
+};
+
+struct _CmpUnspecifiedType;
+using _CmpUnspecifiedParam = void (_CmpUnspecifiedType::*)();
+
+class weak_equality {
+ constexpr explicit weak_equality(_EqResult __val) noexcept : __value_(__val) {}
+
+public:
+ static const weak_equality equivalent;
+ static const weak_equality nonequivalent;
+
+ friend constexpr bool operator==(weak_equality __v, _CmpUnspecifiedParam) noexcept;
+ friend constexpr bool operator==(_CmpUnspecifiedParam, weak_equality __v) noexcept;
+ friend constexpr bool operator!=(weak_equality __v, _CmpUnspecifiedParam) noexcept;
+ friend constexpr bool operator!=(_CmpUnspecifiedParam, weak_equality __v) noexcept;
+ friend constexpr weak_equality operator<=>(weak_equality __v, _CmpUnspecifiedParam) noexcept;
+ friend constexpr weak_equality operator<=>(_CmpUnspecifiedParam, weak_equality __v) noexcept;
+
+ // test helper
+ constexpr bool test_eq(weak_equality const &other) const noexcept {
+ return __value_ == other.__value_;
+ }
+
+private:
+ _EqResult __value_;
+};
+
+inline constexpr weak_equality weak_equality::equivalent(_EqResult::__equiv);
+inline constexpr weak_equality weak_equality::nonequivalent(_EqResult::__nonequiv);
+inline constexpr bool operator==(weak_equality __v, _CmpUnspecifiedParam) noexcept {
+ return __v.__value_ == _EqResult::__zero;
+}
+inline constexpr bool operator==(_CmpUnspecifiedParam, weak_equality __v) noexcept {
+ return __v.__value_ == _EqResult::__zero;
+}
+inline constexpr bool operator!=(weak_equality __v, _CmpUnspecifiedParam) noexcept {
+ return __v.__value_ != _EqResult::__zero;
+}
+inline constexpr bool operator!=(_CmpUnspecifiedParam, weak_equality __v) noexcept {
+ return __v.__value_ != _EqResult::__zero;
+}
+
+inline constexpr weak_equality operator<=>(weak_equality __v, _CmpUnspecifiedParam) noexcept {
+ return __v;
+}
+inline constexpr weak_equality operator<=>(_CmpUnspecifiedParam, weak_equality __v) noexcept {
+ return __v;
+}
+
+class strong_equality {
+ explicit constexpr strong_equality(_EqResult __val) noexcept : __value_(__val) {}
+
+public:
+ static const strong_equality equal;
+ static const strong_equality nonequal;
+ static const strong_equality equivalent;
+ static const strong_equality nonequivalent;
+
+ // conversion
+ constexpr operator weak_equality() const noexcept {
+ return __value_ == _EqResult::__zero ? weak_equality::equivalent
+ : weak_equality::nonequivalent;
+ }
+
+ // comparisons
+ friend constexpr bool operator==(strong_equality __v, _CmpUnspecifiedParam) noexcept;
+ friend constexpr bool operator!=(strong_equality __v, _CmpUnspecifiedParam) noexcept;
+ friend constexpr bool operator==(_CmpUnspecifiedParam, strong_equality __v) noexcept;
+ friend constexpr bool operator!=(_CmpUnspecifiedParam, strong_equality __v) noexcept;
+
+ friend constexpr strong_equality operator<=>(strong_equality __v, _CmpUnspecifiedParam) noexcept;
+ friend constexpr strong_equality operator<=>(_CmpUnspecifiedParam, strong_equality __v) noexcept;
+
+ // test helper
+ constexpr bool test_eq(strong_equality const &other) const noexcept {
+ return __value_ == other.__value_;
+ }
+
+private:
+ _EqResult __value_;
+};
+
+inline constexpr strong_equality strong_equality::equal(_EqResult::__equal);
+inline constexpr strong_equality strong_equality::nonequal(_EqResult::__nonequal);
+inline constexpr strong_equality strong_equality::equivalent(_EqResult::__equiv);
+inline constexpr strong_equality strong_equality::nonequivalent(_EqResult::__nonequiv);
+constexpr bool operator==(strong_equality __v, _CmpUnspecifiedParam) noexcept {
+ return __v.__value_ == _EqResult::__zero;
+}
+constexpr bool operator==(_CmpUnspecifiedParam, strong_equality __v) noexcept {
+ return __v.__value_ == _EqResult::__zero;
+}
+constexpr bool operator!=(strong_equality __v, _CmpUnspecifiedParam) noexcept {
+ return __v.__value_ != _EqResult::__zero;
+}
+constexpr bool operator!=(_CmpUnspecifiedParam, strong_equality __v) noexcept {
+ return __v.__value_ != _EqResult::__zero;
+}
+
+constexpr strong_equality operator<=>(strong_equality __v, _CmpUnspecifiedParam) noexcept {
+ return __v;
+}
+constexpr strong_equality operator<=>(_CmpUnspecifiedParam, strong_equality __v) noexcept {
+ return __v;
+}
+
+class partial_ordering {
+ using _ValueT = signed char;
+ explicit constexpr partial_ordering(_EqResult __v) noexcept
+ : __value_(_ValueT(__v)) {}
+ explicit constexpr partial_ordering(_OrdResult __v) noexcept
+ : __value_(_ValueT(__v)) {}
+ explicit constexpr partial_ordering(_NCmpResult __v) noexcept
+ : __value_(_ValueT(__v)) {}
+
+ constexpr bool __is_ordered() const noexcept {
+ return __value_ != _ValueT(_NCmpResult::__unordered);
+ }
+
+public:
+ // valid values
+ static const partial_ordering less;
+ static const partial_ordering equivalent;
+ static const partial_ordering greater;
+ static const partial_ordering unordered;
+
+ // conversion
+ constexpr operator weak_equality() const noexcept {
+ return __value_ == 0 ? weak_equality::equivalent : weak_equality::nonequivalent;
+ }
+
+ // comparisons
+ friend constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
+ friend constexpr bool operator!=(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
+ friend constexpr bool operator<(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
+ friend constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
+ friend constexpr bool operator>(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
+ friend constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
+ friend constexpr bool operator==(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
+ friend constexpr bool operator!=(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
+ friend constexpr bool operator<(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
+ friend constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
+ friend constexpr bool operator>(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
+ friend constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
+
+ friend constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
+ friend constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
+
+ // test helper
+ constexpr bool test_eq(partial_ordering const &other) const noexcept {
+ return __value_ == other.__value_;
+ }
+
+private:
+ _ValueT __value_;
+};
+
+inline constexpr partial_ordering partial_ordering::less(_OrdResult::__less);
+inline constexpr partial_ordering partial_ordering::equivalent(_EqResult::__equiv);
+inline constexpr partial_ordering partial_ordering::greater(_OrdResult::__greater);
+inline constexpr partial_ordering partial_ordering::unordered(_NCmpResult ::__unordered);
+constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
+ return __v.__is_ordered() && __v.__value_ == 0;
+}
+constexpr bool operator<(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
+ return __v.__is_ordered() && __v.__value_ < 0;
+}
+constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
+ return __v.__is_ordered() && __v.__value_ <= 0;
+}
+constexpr bool operator>(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
+ return __v.__is_ordered() && __v.__value_ > 0;
+}
+constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
+ return __v.__is_ordered() && __v.__value_ >= 0;
+}
+constexpr bool operator==(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
+ return __v.__is_ordered() && 0 == __v.__value_;
+}
+constexpr bool operator<(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
+ return __v.__is_ordered() && 0 < __v.__value_;
+}
+constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
+ return __v.__is_ordered() && 0 <= __v.__value_;
+}
+constexpr bool operator>(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
+ return __v.__is_ordered() && 0 > __v.__value_;
+}
+constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
+ return __v.__is_ordered() && 0 >= __v.__value_;
+}
+constexpr bool operator!=(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
+ return !__v.__is_ordered() || __v.__value_ != 0;
+}
+constexpr bool operator!=(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
+ return !__v.__is_ordered() || __v.__value_ != 0;
+}
+
+constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
+ return __v;
+}
+constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
+ return __v < 0 ? partial_ordering::greater : (__v > 0 ? partial_ordering::less : __v);
+}
+
+class weak_ordering {
+ using _ValueT = signed char;
+ explicit constexpr weak_ordering(_EqResult __v) noexcept : __value_(_ValueT(__v)) {}
+ explicit constexpr weak_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {}
+
+public:
+ static const weak_ordering less;
+ static const weak_ordering equivalent;
+ static const weak_ordering greater;
+
+ // conversions
+ constexpr operator weak_equality() const noexcept {
+ return __value_ == 0 ? weak_equality::equivalent
+ : weak_equality::nonequivalent;
+ }
+ constexpr operator partial_ordering() const noexcept {
+ return __value_ == 0 ? partial_ordering::equivalent
+ : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater);
+ }
+
+ // comparisons
+ friend constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
+ friend constexpr bool operator!=(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
+ friend constexpr bool operator<(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
+ friend constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
+ friend constexpr bool operator>(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
+ friend constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
+ friend constexpr bool operator==(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
+ friend constexpr bool operator!=(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
+ friend constexpr bool operator<(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
+ friend constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
+ friend constexpr bool operator>(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
+ friend constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
+
+ friend constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
+ friend constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
+
+ // test helper
+ constexpr bool test_eq(weak_ordering const &other) const noexcept {
+ return __value_ == other.__value_;
+ }
+
+private:
+ _ValueT __value_;
+};
+
+inline constexpr weak_ordering weak_ordering::less(_OrdResult::__less);
+inline constexpr weak_ordering weak_ordering::equivalent(_EqResult::__equiv);
+inline constexpr weak_ordering weak_ordering::greater(_OrdResult::__greater);
+constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
+ return __v.__value_ == 0;
+}
+constexpr bool operator!=(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
+ return __v.__value_ != 0;
+}
+constexpr bool operator<(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
+ return __v.__value_ < 0;
+}
+constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
+ return __v.__value_ <= 0;
+}
+constexpr bool operator>(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
+ return __v.__value_ > 0;
+}
+constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
+ return __v.__value_ >= 0;
+}
+constexpr bool operator==(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
+ return 0 == __v.__value_;
+}
+constexpr bool operator!=(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
+ return 0 != __v.__value_;
+}
+constexpr bool operator<(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
+ return 0 < __v.__value_;
+}
+constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
+ return 0 <= __v.__value_;
+}
+constexpr bool operator>(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
+ return 0 > __v.__value_;
+}
+constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
+ return 0 >= __v.__value_;
+}
+
+constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
+ return __v;
+}
+constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
+ return __v < 0 ? weak_ordering::greater : (__v > 0 ? weak_ordering::less : __v);
+}
+
+class strong_ordering {
+ using _ValueT = signed char;
+ explicit constexpr strong_ordering(_EqResult __v) noexcept : __value_(static_cast<signed char>(__v)) {}
+ explicit constexpr strong_ordering(_OrdResult __v) noexcept : __value_(static_cast<signed char>(__v)) {}
+
+public:
+ static const strong_ordering less;
+ static const strong_ordering equal;
+ static const strong_ordering equivalent;
+ static const strong_ordering greater;
+
+ // conversions
+ constexpr operator weak_equality() const noexcept {
+ return __value_ == 0 ? weak_equality::equivalent
+ : weak_equality::nonequivalent;
+ }
+ constexpr operator strong_equality() const noexcept {
+ return __value_ == 0 ? strong_equality::equal
+ : strong_equality::nonequal;
+ }
+ constexpr operator partial_ordering() const noexcept {
+ return __value_ == 0 ? partial_ordering::equivalent
+ : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater);
+ }
+ constexpr operator weak_ordering() const noexcept {
+ return __value_ == 0 ? weak_ordering::equivalent
+ : (__value_ < 0 ? weak_ordering::less : weak_ordering::greater);
+ }
+
+ // comparisons
+ friend constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
+ friend constexpr bool operator!=(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
+ friend constexpr bool operator<(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
+ friend constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
+ friend constexpr bool operator>(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
+ friend constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
+ friend constexpr bool operator==(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
+ friend constexpr bool operator!=(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
+ friend constexpr bool operator<(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
+ friend constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
+ friend constexpr bool operator>(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
+ friend constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
+
+ friend constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
+ friend constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
+
+ // test helper
+ constexpr bool test_eq(strong_ordering const &other) const noexcept {
+ return __value_ == other.__value_;
+ }
+
+private:
+ _ValueT __value_;
+};
+
+inline constexpr strong_ordering strong_ordering::less(_OrdResult::__less);
+inline constexpr strong_ordering strong_ordering::equal(_EqResult::__equal);
+inline constexpr strong_ordering strong_ordering::equivalent(_EqResult::__equiv);
+inline constexpr strong_ordering strong_ordering::greater(_OrdResult::__greater);
+
+constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
+ return __v.__value_ == 0;
+}
+constexpr bool operator!=(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
+ return __v.__value_ != 0;
+}
+constexpr bool operator<(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
+ return __v.__value_ < 0;
+}
+constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
+ return __v.__value_ <= 0;
+}
+constexpr bool operator>(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
+ return __v.__value_ > 0;
+}
+constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
+ return __v.__value_ >= 0;
+}
+constexpr bool operator==(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
+ return 0 == __v.__value_;
+}
+constexpr bool operator!=(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
+ return 0 != __v.__value_;
+}
+constexpr bool operator<(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
+ return 0 < __v.__value_;
+}
+constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
+ return 0 <= __v.__value_;
+}
+constexpr bool operator>(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
+ return 0 > __v.__value_;
+}
+constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
+ return 0 >= __v.__value_;
+}
+
+constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
+ return __v;
+}
+constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
+ return __v < 0 ? strong_ordering::greater : (__v > 0 ? strong_ordering::less : __v);
+}
+
+// named comparison functions
+constexpr bool is_eq(weak_equality __cmp) noexcept { return __cmp == 0; }
+constexpr bool is_neq(weak_equality __cmp) noexcept { return __cmp != 0; }
+constexpr bool is_lt(partial_ordering __cmp) noexcept { return __cmp < 0; }
+constexpr bool is_lteq(partial_ordering __cmp) noexcept { return __cmp <= 0; }
+constexpr bool is_gt(partial_ordering __cmp) noexcept { return __cmp > 0; }
+constexpr bool is_gteq(partial_ordering __cmp) noexcept { return __cmp >= 0; }
+
+} // namespace __1
+} // end namespace std
+
+#endif // STD_COMPARE_H
diff --git a/src/llvm-project/clang/test/CodeGenCXX/PR19955.cpp b/src/llvm-project/clang/test/CodeGenCXX/PR19955.cpp
new file mode 100644
index 0000000..5175b74
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/PR19955.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -triple i686-windows-msvc -fms-extensions -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -fms-extensions -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s | FileCheck %s --check-prefix X64
+
+extern int __declspec(dllimport) var;
+extern void __declspec(dllimport) fun();
+
+extern int *varp;
+int *varp = &var;
+// CHECK-DAG: @"?varp@@3PAHA" = dso_local global i32* null
+// X64-DAG: @"?varp@@3PEAHEA" = dso_local global i32* null
+
+extern void (*funp)();
+void (*funp)() = &fun;
+// CHECK-DAG: @"?funp@@3P6AXXZA" = dso_local global void ()* null
+// X64-DAG: @"?funp@@3P6AXXZEA" = dso_local global void ()* null
+
+// CHECK-LABEL: @"??__Evarp@@YAXXZ"
+// CHECK-DAG: store i32* @"?var@@3HA", i32** @"?varp@@3PAHA"
+
+// X64-LABEL: @"??__Evarp@@YAXXZ"
+// X64-DAG: store i32* @"?var@@3HA", i32** @"?varp@@3PEAHEA"
+
+// CHECK-LABEL: @"??__Efunp@@YAXXZ"()
+// CHECK-DAG: store void ()* @"?fun@@YAXXZ", void ()** @"?funp@@3P6AXXZA"
+
+// X64-LABEL: @"??__Efunp@@YAXXZ"()
+// X64-DAG: store void ()* @"?fun@@YAXXZ", void ()** @"?funp@@3P6AXXZEA"
diff --git a/src/llvm-project/clang/test/CodeGenCXX/PR20038.cpp b/src/llvm-project/clang/test/CodeGenCXX/PR20038.cpp
new file mode 100644
index 0000000..195e4e5
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/PR20038.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -debug-info-kind=limited -mllvm -no-discriminators -emit-llvm %s -o - | FileCheck %s
+
+struct C {
+ ~C();
+};
+extern bool b;
+// CHECK: call {{.*}}, !dbg [[DTOR_CALL1_LOC:![0-9]*]]
+// CHECK: call {{.*}}, !dbg [[DTOR_CALL2_LOC:![0-9]*]]
+// CHECK: [[FUN1:.*]] = distinct !DISubprogram(name: "fun1",{{.*}} DISPFlagDefinition
+// CHECK: [[DTOR_CALL1_LOC]] = !DILocation(line: [[@LINE+1]], scope: [[FUN1]])
+void fun1() { b && (C(), 1); }
+// CHECK: [[FUN2:.*]] = distinct !DISubprogram(name: "fun2",{{.*}} DISPFlagDefinition
+// CHECK: [[DTOR_CALL2_LOC]] = !DILocation(line: [[@LINE+1]], scope: [[FUN2]])
+bool fun2() { return (C(), b) && 0; }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/PR24289.cpp b/src/llvm-project/clang/test/CodeGenCXX/PR24289.cpp
new file mode 100644
index 0000000..364b5b2
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/PR24289.cpp
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-pc-linux-gnu -std=c++11 | FileCheck %s
+
+namespace std {
+template <class T>
+struct initializer_list {
+ const T *Begin;
+ __SIZE_TYPE__ Size;
+
+ constexpr initializer_list(const T *B, __SIZE_TYPE__ S)
+ : Begin(B), Size(S) {}
+};
+}
+
+void f() {
+ static std::initializer_list<std::initializer_list<int>> a{
+ {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}};
+ static std::initializer_list<std::initializer_list<int>> b{
+ {0}, {0}, {0}, {0}};
+ static std::initializer_list<std::initializer_list<int>> c{
+ {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}};
+ static std::initializer_list<std::initializer_list<int>> d{
+ {0}, {0}, {0}, {0}, {0}};
+ static std::initializer_list<std::initializer_list<int>> e{
+ {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}};
+}
+
+// CHECK-DAG: @_ZZ1fvE1a = internal global %{{.*}} { %{{.*}}* getelementptr inbounds ([14 x %{{.*}}], [14 x %{{.*}}]
+// CHECK-DAG: * @_ZGRZ1fvE1a_, i32 0, i32 0), i64 14 }
+// CHECK-DAG: @_ZGRZ1fvE1a0_ = internal constant [1 x i32] zeroinitializer
+// CHECK-DAG: @_ZGRZ1fvE1a1_ = internal constant [1 x i32] zeroinitializer
+// CHECK-DAG: @_ZGRZ1fvE1a2_ = internal constant [1 x i32] zeroinitializer
+// CHECK-DAG: @_ZGRZ1fvE1a3_ = internal constant [1 x i32] zeroinitializer
+// CHECK-DAG: @_ZGRZ1fvE1a4_ = internal constant [1 x i32] zeroinitializer
+// CHECK-DAG: @_ZGRZ1fvE1a5_ = internal constant [1 x i32] zeroinitializer
+// CHECK-DAG: @_ZGRZ1fvE1a6_ = internal constant [1 x i32] zeroinitializer
+// CHECK-DAG: @_ZGRZ1fvE1a7_ = internal constant [1 x i32] zeroinitializer
+// CHECK-DAG: @_ZGRZ1fvE1a8_ = internal constant [1 x i32] zeroinitializer
+// CHECK-DAG: @_ZGRZ1fvE1a9_ = internal constant [1 x i32] zeroinitializer
+// CHECK-DAG: @_ZGRZ1fvE1aA_ = internal constant [1 x i32] zeroinitializer
+// CHECK-DAG: @_ZGRZ1fvE1aB_ = internal constant [1 x i32] zeroinitializer
+// CHECK-DAG: @_ZGRZ1fvE1aC_ = internal constant [1 x i32] zeroinitializer
+// CHECK-DAG: @_ZGRZ1fvE1aD_ = internal constant [1 x i32] zeroinitializer
+// CHECK-DAG: @_ZGRZ1fvE1a_ = internal constant [14 x %{{.*}}] [%{{.*}} { i32* getelementptr inbounds ([1 x i32], [1 x i32]* @_ZGRZ1fvE1a0_, i32 0, i32 0), i64 1 }, %{{.*}} { i32* getelementptr inbounds ([1 x i32], [1 x i32]* @_ZGRZ1fvE1a1_, i32 0, i32 0), i64 1 }, %{{.*}} { i32* getelementptr inbounds ([1 x i32], [1 x i32]* @_ZGRZ1fvE1a2_, i32 0, i32 0), i64 1 }, %{{.*}} { i32* getelementptr inbounds ([1 x i32], [1 x i32]* @_ZGRZ1fvE1a3_, i32 0, i32 0), i64 1 }, %{{.*}} { i32* getelementptr inbounds ([1 x i32], [1 x i32]* @_ZGRZ1fvE1a4_, i32 0, i32 0), i64 1 }, %{{.*}} { i32* getelementptr inbounds ([1 x i32], [1 x i32]* @_ZGRZ1fvE1a5_, i32 0, i32 0), i64 1 }, %{{.*}} { i32* getelementptr inbounds ([1 x i32], [1 x i32]* @_ZGRZ1fvE1a6_, i32 0, i32 0), i64 1 }, %{{.*}} { i32* getelementptr inbounds ([1 x i32], [1 x i32]* @_ZGRZ1fvE1a7_, i32 0, i32 0), i64 1 }, %{{.*}} { i32* getelementptr inbounds ([1 x i32], [1 x i32]* @_ZGRZ1fvE1a8_, i32 0, i32 0), i64 1 }, %{{.*}} { i32* getelementptr inbounds ([1 x i32], [1 x i32]* @_ZGRZ1fvE1a9_, i32 0, i32 0), i64 1 }, %{{.*}} { i32* getelementptr inbounds ([1 x i32], [1 x i32]* @_ZGRZ1fvE1aA_, i32 0, i32 0), i64 1 }, %{{.*}} { i32* getelementptr inbounds ([1 x i32], [1 x i32]* @_ZGRZ1fvE1aB_, i32 0, i32 0), i64 1 }, %{{.*}} { i32* getelementptr inbounds ([1 x i32], [1 x i32]* @_ZGRZ1fvE1aC_, i32 0, i32 0), i64 1 }, %{{.*}} { i32* getelementptr inbounds ([1 x i32], [1 x i32]* @_ZGRZ1fvE1aD_, i32 0, i32 0), i64 1 }]
+// CHECK-DAG: @_ZZ1fvE1b = internal global %{{.*}} { %{{.*}}* getelementptr inbounds ([4 x %{{.*}}], [4 x %{{.*}}]*
+// CHECK-DAG: @_ZGRZ1fvE1b_, i32 0, i32 0), i64 4 }
+// CHECK-DAG: @_ZGRZ1fvE1b0_ = internal constant [1 x i32] zeroinitializer
+// CHECK-DAG: @_ZGRZ1fvE1b1_ = internal constant [1 x i32] zeroinitializer
+// CHECK-DAG: @_ZGRZ1fvE1b2_ = internal constant [1 x i32] zeroinitializer
+// CHECK-DAG: @_ZGRZ1fvE1b3_ = internal constant [1 x i32] zeroinitializer
+// CHECK-DAG: @_ZGRZ1fvE1b_ = internal constant [4 x %{{.*}}] [%{{.*}} { i32* getelementptr inbounds ([1 x i32], [1 x i32]* @_ZGRZ1fvE1b0_, i32 0, i32 0), i64 1 }, %{{.*}} { i32* getelementptr inbounds ([1 x i32], [1 x i32]* @_ZGRZ1fvE1b1_, i32 0, i32 0), i64 1 }, %{{.*}} { i32* getelementptr inbounds ([1 x i32], [1 x i32]* @_ZGRZ1fvE1b2_, i32 0, i32 0), i64 1 }, %{{.*}} { i32* getelementptr inbounds ([1 x i32], [1 x i32]* @_ZGRZ1fvE1b3_, i32 0, i32 0), i64 1 }]
+// CHECK-DAG: @_ZZ1fvE1c = internal global %{{.*}} { %{{.*}}* getelementptr inbounds ([9 x %{{.*}}], [9 x %{{.*}}]*
+// CHECK-DAG: @_ZGRZ1fvE1c_, i32 0, i32 0), i64 9 }
+// CHECK-DAG: @_ZGRZ1fvE1c0_ = internal constant [1 x i32] zeroinitializer
+// CHECK-DAG: @_ZGRZ1fvE1c1_ = internal constant [1 x i32] zeroinitializer
+// CHECK-DAG: @_ZGRZ1fvE1c2_ = internal constant [1 x i32] zeroinitializer
+// CHECK-DAG: @_ZGRZ1fvE1c3_ = internal constant [1 x i32] zeroinitializer
+// CHECK-DAG: @_ZGRZ1fvE1c4_ = internal constant [1 x i32] zeroinitializer
+// CHECK-DAG: @_ZGRZ1fvE1c5_ = internal constant [1 x i32] zeroinitializer
+// CHECK-DAG: @_ZGRZ1fvE1c6_ = internal constant [1 x i32] zeroinitializer
+// CHECK-DAG: @_ZGRZ1fvE1c7_ = internal constant [1 x i32] zeroinitializer
+// CHECK-DAG: @_ZGRZ1fvE1c8_ = internal constant [1 x i32] zeroinitializer
+// CHECK-DAG: @_ZGRZ1fvE1c_ = internal constant [9 x %{{.*}}] [%{{.*}} { i32* getelementptr inbounds ([1 x i32], [1 x i32]* @_ZGRZ1fvE1c0_, i32 0, i32 0), i64 1 }, %{{.*}} { i32* getelementptr inbounds ([1 x i32], [1 x i32]* @_ZGRZ1fvE1c1_, i32 0, i32 0), i64 1 }, %{{.*}} { i32* getelementptr inbounds ([1 x i32], [1 x i32]* @_ZGRZ1fvE1c2_, i32 0, i32 0), i64 1 }, %{{.*}} { i32* getelementptr inbounds ([1 x i32], [1 x i32]* @_ZGRZ1fvE1c3_, i32 0, i32 0), i64 1 }, %{{.*}} { i32* getelementptr inbounds ([1 x i32], [1 x i32]* @_ZGRZ1fvE1c4_, i32 0, i32 0), i64 1 }, %{{.*}} { i32* getelementptr inbounds ([1 x i32], [1 x i32]* @_ZGRZ1fvE1c5_, i32 0, i32 0), i64 1 }, %{{.*}} { i32* getelementptr inbounds ([1 x i32], [1 x i32]* @_ZGRZ1fvE1c6_, i32 0, i32 0), i64 1 }, %{{.*}} { i32* getelementptr inbounds ([1 x i32], [1 x i32]* @_ZGRZ1fvE1c7_, i32 0, i32 0), i64 1 }, %{{.*}} { i32* getelementptr inbounds ([1 x i32], [1 x i32]* @_ZGRZ1fvE1c8_, i32 0, i32 0), i64 1 }]
+// CHECK-DAG: @_ZZ1fvE1d = internal global %{{.*}} { %{{.*}}* getelementptr inbounds ([5 x %{{.*}}], [5 x %{{.*}}]* @_ZGRZ1fvE1d_, i32 0, i32 0), i64 5 }
+// CHECK-DAG: @_ZGRZ1fvE1d0_ = internal constant [1 x i32] zeroinitializer
+// CHECK-DAG: @_ZGRZ1fvE1d1_ = internal constant [1 x i32] zeroinitializer
+// CHECK-DAG: @_ZGRZ1fvE1d2_ = internal constant [1 x i32] zeroinitializer
+// CHECK-DAG: @_ZGRZ1fvE1d3_ = internal constant [1 x i32] zeroinitializer
+// CHECK-DAG: @_ZGRZ1fvE1d4_ = internal constant [1 x i32] zeroinitializer
+// CHECK-DAG: @_ZGRZ1fvE1d_ = internal constant [5 x %{{.*}}] [%{{.*}} { i32* getelementptr inbounds ([1 x i32], [1 x i32]* @_ZGRZ1fvE1d0_, i32 0, i32 0), i64 1 }, %{{.*}} { i32* getelementptr inbounds ([1 x i32], [1 x i32]* @_ZGRZ1fvE1d1_, i32 0, i32 0), i64 1 }, %{{.*}} { i32* getelementptr inbounds ([1 x i32], [1 x i32]* @_ZGRZ1fvE1d2_, i32 0, i32 0), i64 1 }, %{{.*}} { i32* getelementptr inbounds ([1 x i32], [1 x i32]* @_ZGRZ1fvE1d3_, i32 0, i32 0), i64 1 }, %{{.*}} { i32* getelementptr inbounds ([1 x i32], [1 x i32]* @_ZGRZ1fvE1d4_, i32 0, i32 0), i64 1 }]
+// CHECK-DAG: @_ZZ1fvE1e = internal global %{{.*}} { %{{.*}}* getelementptr inbounds ([11 x %{{.*}}], [11 x %{{.*}}]* @_ZGRZ1fvE1e_, i32 0, i32 0), i64 11 }
+// CHECK-DAG: @_ZGRZ1fvE1e0_ = internal constant [1 x i32] zeroinitializer
+// CHECK-DAG: @_ZGRZ1fvE1e1_ = internal constant [1 x i32] zeroinitializer
+// CHECK-DAG: @_ZGRZ1fvE1e2_ = internal constant [1 x i32] zeroinitializer
+// CHECK-DAG: @_ZGRZ1fvE1e3_ = internal constant [1 x i32] zeroinitializer
+// CHECK-DAG: @_ZGRZ1fvE1e4_ = internal constant [1 x i32] zeroinitializer
+// CHECK-DAG: @_ZGRZ1fvE1e5_ = internal constant [1 x i32] zeroinitializer
+// CHECK-DAG: @_ZGRZ1fvE1e6_ = internal constant [1 x i32] zeroinitializer
+// CHECK-DAG: @_ZGRZ1fvE1e7_ = internal constant [1 x i32] zeroinitializer
+// CHECK-DAG: @_ZGRZ1fvE1e8_ = internal constant [1 x i32] zeroinitializer
+// CHECK-DAG: @_ZGRZ1fvE1e9_ = internal constant [1 x i32] zeroinitializer
+// CHECK-DAG: @_ZGRZ1fvE1eA_ = internal constant [1 x i32] zeroinitializer
+// CHECK-DAG: @_ZGRZ1fvE1e_ = internal constant [11 x %{{.*}}] [%{{.*}} { i32* getelementptr inbounds ([1 x i32], [1 x i32]* @_ZGRZ1fvE1e0_, i32 0, i32 0), i64 1 }, %{{.*}} { i32* getelementptr inbounds ([1 x i32], [1 x i32]* @_ZGRZ1fvE1e1_, i32 0, i32 0), i64 1 }, %{{.*}} { i32* getelementptr inbounds ([1 x i32], [1 x i32]* @_ZGRZ1fvE1e2_, i32 0, i32 0), i64 1 }, %{{.*}} { i32* getelementptr inbounds ([1 x i32], [1 x i32]* @_ZGRZ1fvE1e3_, i32 0, i32 0), i64 1 }, %{{.*}} { i32* getelementptr inbounds ([1 x i32], [1 x i32]* @_ZGRZ1fvE1e4_, i32 0, i32 0), i64 1 }, %{{.*}} { i32* getelementptr inbounds ([1 x i32], [1 x i32]* @_ZGRZ1fvE1e5_, i32 0, i32 0), i64 1 }, %{{.*}} { i32* getelementptr inbounds ([1 x i32], [1 x i32]* @_ZGRZ1fvE1e6_, i32 0, i32 0), i64 1 }, %{{.*}} { i32* getelementptr inbounds ([1 x i32], [1 x i32]* @_ZGRZ1fvE1e7_, i32 0, i32 0), i64 1 }, %{{.*}} { i32* getelementptr inbounds ([1 x i32], [1 x i32]* @_ZGRZ1fvE1e8_, i32 0, i32 0), i64 1 }, %{{.*}} { i32* getelementptr inbounds ([1 x i32], [1 x i32]* @_ZGRZ1fvE1e9_, i32 0, i32 0), i64 1 }, %{{.*}} { i32* getelementptr inbounds ([1 x i32], [1 x i32]* @_ZGRZ1fvE1eA_, i32 0, i32 0), i64 1 }]
diff --git a/src/llvm-project/clang/test/CodeGenCXX/PR26569.cpp b/src/llvm-project/clang/test/CodeGenCXX/PR26569.cpp
new file mode 100644
index 0000000..379b50c
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/PR26569.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple i686-pc-win32 -fms-extensions -emit-llvm -O1 -disable-llvm-passes %s -o - | FileCheck %s
+
+class __declspec(dllimport) A {
+ virtual void m_fn1();
+};
+template <typename>
+class B : virtual A {};
+
+extern template class __declspec(dllimport) B<int>;
+class __declspec(dllexport) C : B<int> {};
+
+// CHECK-DAG: @[[VTABLE_C:.*]] = private unnamed_addr constant { [2 x i8*] } { [2 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"??_R4C@@6B@" to i8*), i8* bitcast (void (%class.A*)* @"?m_fn1@A@@EAEXXZ" to i8*)] }
+// CHECK-DAG: @[[VTABLE_B:.*]] = private unnamed_addr constant { [2 x i8*] } { [2 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"??_R4?$B@H@@6B@" to i8*), i8* bitcast (void (%class.A*)* @"?m_fn1@A@@EAEXXZ" to i8*)] }, comdat($"??_S?$B@H@@6B@")
+// CHECK-DAG: @[[VTABLE_A:.*]] = private unnamed_addr constant { [2 x i8*] } { [2 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"??_R4A@@6B@" to i8*), i8* bitcast (void (%class.A*)* @"?m_fn1@A@@EAEXXZ" to i8*)] }, comdat($"??_SA@@6B@")
+
+// CHECK-DAG: @"??_7C@@6B@" = dllexport unnamed_addr alias i8*, getelementptr inbounds ({ [2 x i8*] }, { [2 x i8*] }* @[[VTABLE_C]], i32 0, i32 0, i32 1)
+// CHECK-DAG: @"??_S?$B@H@@6B@" = unnamed_addr alias i8*, getelementptr inbounds ({ [2 x i8*] }, { [2 x i8*] }* @[[VTABLE_B]], i32 0, i32 0, i32 1)
+// CHECK-DAG: @"??_SA@@6B@" = unnamed_addr alias i8*, getelementptr inbounds ({ [2 x i8*] }, { [2 x i8*] }* @[[VTABLE_A]], i32 0, i32 0, i32 1)
+
+// CHECK-DAG: @"??_8?$B@H@@7B@" = available_externally dllimport unnamed_addr constant [2 x i32] [i32 0, i32 4]
diff --git a/src/llvm-project/clang/test/CodeGenCXX/PR28220.cpp b/src/llvm-project/clang/test/CodeGenCXX/PR28220.cpp
new file mode 100644
index 0000000..5863b6d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/PR28220.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 %s -triple i686-pc-win32 -fms-extensions -emit-llvm -o - | FileCheck %s
+
+template <typename>
+struct __declspec(dllimport) S {
+ S();
+};
+
+template <typename T>
+struct __declspec(dllimport) U {
+ static S<T> u;
+};
+
+template <typename T>
+S<T> U<T>::u;
+
+template S<int> U<int>::u;
+// CHECK-NOT: define internal void @"??__Eu@?$U@H@@2U?$S@H@@A@YAXXZ"(
+
+S<int> &i = U<int>::u;
diff --git a/src/llvm-project/clang/test/CodeGenCXX/PR28523.cpp b/src/llvm-project/clang/test/CodeGenCXX/PR28523.cpp
new file mode 100644
index 0000000..4c3a81c
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/PR28523.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -std=c++14 -verify -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s
+// expected-no-diagnostics
+
+template <class F> void parallel_loop(F &&f) { f(0); }
+
+//CHECK-LABEL: @main
+int main() {
+// CHECK: [[X_ADDR:%.+]] = alloca i32,
+ int x;
+// CHECK: getelementptr inbounds
+// CHECK: store i32* [[X_ADDR]], i32** %
+// CHECK: call
+ parallel_loop([&](auto y) {
+#pragma clang __debug captured
+ {
+ x = y;
+ };
+ });
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/PR37481.cpp b/src/llvm-project/clang/test/CodeGenCXX/PR37481.cpp
new file mode 100644
index 0000000..fba2ffd
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/PR37481.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -o /dev/null -emit-llvm -std=c++17 -triple x86_64-pc-windows-msvc %s
+
+struct Foo {
+ virtual void f();
+ virtual void g();
+};
+
+void Foo::f() {}
+void Foo::g() {}
+
+template <void (Foo::*)()>
+void h() {}
+
+void x() {
+ h<&Foo::f>();
+ h<&Foo::g>();
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/PR4827-cast.cpp b/src/llvm-project/clang/test/CodeGenCXX/PR4827-cast.cpp
new file mode 100644
index 0000000..34a840c
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/PR4827-cast.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s
+struct A;
+struct B;
+extern A *f();
+void a() { (B *) f(); }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/PR4983-constructor-conversion.cpp b/src/llvm-project/clang/test/CodeGenCXX/PR4983-constructor-conversion.cpp
new file mode 100644
index 0000000..797a1ba
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/PR4983-constructor-conversion.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -emit-llvm-only %s
+
+struct A {
+ A(const char *s){}
+};
+
+struct B {
+ A a;
+
+ B() : a("test") { }
+};
+
+void f() {
+ A a("test");
+}
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/PR5050-constructor-conversion.cpp b/src/llvm-project/clang/test/CodeGenCXX/PR5050-constructor-conversion.cpp
new file mode 100644
index 0000000..ce6cc0e
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/PR5050-constructor-conversion.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm %s -o - | \
+// RUN: FileCheck %s
+// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -emit-llvm %s -o - | \
+// RUN: FileCheck %s
+
+struct A { A(const A&, int i1 = 1); };
+
+struct B : A { };
+
+A f(const B &b) {
+ return b;
+}
+
+// CHECK: call void @_ZN1AC1ERKS_i
diff --git a/src/llvm-project/clang/test/CodeGenCXX/PR5093-static-member-function.cpp b/src/llvm-project/clang/test/CodeGenCXX/PR5093-static-member-function.cpp
new file mode 100644
index 0000000..6811351
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/PR5093-static-member-function.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s -emit-llvm -triple %itanium_abi_triple -o - | FileCheck %s
+struct a {
+ static void f();
+};
+
+void g(a *a) {
+ // CHECK: call {{.*}}void @_ZN1a1fEv()
+ a->f();
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/PR5834-constructor-conversion.cpp b/src/llvm-project/clang/test/CodeGenCXX/PR5834-constructor-conversion.cpp
new file mode 100644
index 0000000..044d8e5
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/PR5834-constructor-conversion.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s
+
+// PR5834
+struct ASTMultiMover {};
+struct ASTMultiPtr {
+ ASTMultiPtr();
+ ASTMultiPtr(ASTMultiPtr&);
+ ASTMultiPtr(ASTMultiMover mover);
+ operator ASTMultiMover();
+};
+void f1() {
+ extern void f0(ASTMultiPtr);
+ f0(ASTMultiPtr());
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/PR5863-unreachable-block.cpp b/src/llvm-project/clang/test/CodeGenCXX/PR5863-unreachable-block.cpp
new file mode 100644
index 0000000..50d1731
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/PR5863-unreachable-block.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -emit-llvm-only %s
+
+// PR5863
+class E { };
+
+void P1() {
+ try {
+ int a=0, b=0;
+ if (a > b) // simply filling in 0 or 1 doesn't trigger the assertion
+ throw E(); // commenting out 'if' or 'throw' 'fixes' the assertion failure
+ try { } catch (...) { } // empty try/catch block needed for failure
+ } catch (...) { } // this try/catch block needed for failure
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/PR6474.cpp b/src/llvm-project/clang/test/CodeGenCXX/PR6474.cpp
new file mode 100644
index 0000000..0b155ce
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/PR6474.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 %s -emit-llvm-only
+
+namespace test0 {
+template <typename T> struct X {
+ virtual void foo();
+ virtual void bar();
+ virtual void baz();
+};
+
+template <typename T> void X<T>::foo() {}
+template <typename T> void X<T>::bar() {}
+template <typename T> void X<T>::baz() {}
+
+template <> void X<char>::foo() {}
+template <> void X<char>::bar() {}
+}
+
+namespace test1 {
+template <typename T> struct X {
+ virtual void foo();
+ virtual void bar();
+ virtual void baz();
+};
+
+template <typename T> void X<T>::foo() {}
+template <typename T> void X<T>::bar() {}
+template <typename T> void X<T>::baz() {}
+
+template <> void X<char>::bar() {}
+template <> void X<char>::foo() {}
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/__null.cpp b/src/llvm-project/clang/test/CodeGenCXX/__null.cpp
new file mode 100644
index 0000000..8a17797
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/__null.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s -emit-llvm -o %t
+
+int* a = __null;
+int b = __null;
+
+void f() {
+ int* c = __null;
+ int d = __null;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/aarch64-aapcs-zerolength-bitfield.cpp b/src/llvm-project/clang/test/CodeGenCXX/aarch64-aapcs-zerolength-bitfield.cpp
new file mode 100644
index 0000000..8b403fa
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/aarch64-aapcs-zerolength-bitfield.cpp
@@ -0,0 +1,249 @@
+// REQUIRES: aarch64-registered-target
+// RUN: %clang_cc1 -triple aarch64-linux-gnu -x c++ -std=c++1z %s -verify
+// expected-no-diagnostics
+
+#include <stddef.h>
+
+struct t1
+{
+ int foo : 1;
+ char : 0;
+ char bar;
+
+};
+static_assert(offsetof(struct t1, bar) == 1);
+static_assert(sizeof(struct t1) == 4);
+
+struct t2
+{
+ int foo : 1;
+ short : 0;
+ char bar;
+};
+static_assert(offsetof(struct t2, bar) == 2);
+static_assert(sizeof(struct t2) == 4);
+
+struct t3
+{
+ int foo : 1;
+ int : 0;
+ char bar;
+};
+static_assert(offsetof(struct t3, bar) == 4);
+static_assert(sizeof(struct t3) == 8);
+
+struct t4
+{
+ int foo : 1;
+ long : 0;
+ char bar;
+};
+static_assert(offsetof(struct t4, bar) == 8);
+static_assert(sizeof(struct t4) == 16);
+
+struct t5
+{
+ int foo : 1;
+ long long : 0;
+ char bar;
+};
+static_assert(offsetof(struct t5, bar) == 8);
+static_assert(sizeof(struct t5) == 16);
+
+struct t6
+{
+ int foo : 1;
+ char : 0;
+ char bar : 1;
+ char bar2;
+};
+static_assert(offsetof(struct t6, bar2) == 2);
+static_assert(sizeof(struct t6) == 4);
+
+struct t7
+{
+ int foo : 1;
+ short : 0;
+ char bar1 : 1;
+ char bar2;
+};
+static_assert(offsetof(struct t7, bar2) == 3);
+static_assert(sizeof(struct t7) == 4);
+
+struct t8
+{
+ int foo : 1;
+ int : 0;
+ char bar1 : 1;
+ char bar2;
+};
+static_assert(offsetof(struct t8, bar2) == 5);
+static_assert(sizeof(struct t8) == 8);
+
+struct t9
+{
+ int foo : 1;
+ long : 0;
+ char bar1 : 1;
+ char bar2;
+};
+static_assert(offsetof(struct t9, bar2) == 9);
+static_assert(sizeof(struct t9) == 16);
+
+struct t10
+{
+ int foo : 1;
+ long long : 0;
+ char bar1 : 1;
+ char bar2;
+};
+static_assert(offsetof(struct t10, bar2) == 9);
+static_assert(sizeof(struct t10) == 16);
+
+struct t11
+{
+ int foo : 1;
+ long long : 0;
+ char : 0;
+ char bar1 : 1;
+ char bar2;
+};
+static_assert(offsetof(struct t11, bar2) == 9);
+static_assert(sizeof(struct t11) == 16);
+
+struct t12
+{
+ int foo : 1;
+ char : 0;
+ long long : 0;
+ char : 0;
+ char bar;
+};
+static_assert(offsetof(struct t12, bar) == 8);
+static_assert(sizeof(struct t12) == 16);
+
+struct t13
+{
+ char foo;
+ long : 0;
+ char bar;
+};
+static_assert(offsetof(struct t13, bar) == 8);
+static_assert(sizeof(struct t13) == 16);
+
+struct t14
+{
+ char foo1;
+ int : 0;
+ char foo2 : 1;
+ short foo3 : 16;
+ char : 0;
+ short foo4 : 16;
+ char bar1;
+ int : 0;
+ char bar2;
+};
+static_assert(offsetof(struct t14, bar1) == 10);
+static_assert(offsetof(struct t14, bar2) == 12);
+static_assert(sizeof(struct t14) == 16);
+
+struct t15
+{
+ char foo;
+ char : 0;
+ int : 0;
+ char bar;
+ long : 0;
+ char : 0;
+};
+static_assert(offsetof(struct t15, bar) == 4);
+static_assert(sizeof(struct t15) == 8);
+
+struct t16
+{
+ long : 0;
+ char bar;
+};
+static_assert(offsetof(struct t16, bar) == 0);
+static_assert(sizeof(struct t16) == 8);
+
+struct t17
+{
+ char foo;
+ long : 0;
+ long : 0;
+ char : 0;
+ char bar;
+};
+static_assert(offsetof(struct t17, bar) == 8);
+static_assert(sizeof(struct t17) == 16);
+
+struct t18
+{
+ long : 0;
+ long : 0;
+ char : 0;
+};
+static_assert(sizeof(struct t18) == 8);
+
+struct t19
+{
+ char foo1;
+ long foo2 : 1;
+ char : 0;
+ long foo3 : 32;
+ char bar;
+};
+static_assert(offsetof(struct t19, bar) == 6);
+static_assert(sizeof(struct t19) == 8);
+
+struct t20
+{
+ short : 0;
+ int foo : 1;
+ long : 0;
+ char bar;
+};
+static_assert(offsetof(struct t20, bar) == 8);
+static_assert(sizeof(struct t20) == 16);
+
+struct t21
+{
+ short : 0;
+ int foo1 : 1;
+ char : 0;
+ int foo2 : 16;
+ long : 0;
+ char bar1;
+ int bar2;
+ long bar3;
+ char foo3 : 8;
+ char : 0;
+ long : 0;
+ int foo4 : 32;
+ short foo5: 1;
+ long bar4;
+ short foo6: 16;
+ short foo7: 16;
+ short foo8: 16;
+};
+static_assert(offsetof(struct t21, bar1) == 8);
+static_assert(offsetof(struct t21, bar2) == 12);
+static_assert(offsetof(struct t21, bar3) == 16);
+static_assert(offsetof(struct t21, bar4) == 40);
+static_assert(sizeof(struct t21) == 56);
+
+// The rules also apply to anonymous bitfields with non-zero length.
+struct t22
+{
+ char foo;
+ short :2;
+ char bar;
+};
+static_assert(alignof(struct t22) == 2);
+static_assert(offsetof(struct t22, bar) == 2);
+
+int main() {
+ return 0;
+}
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/aarch64-arguments.cpp b/src/llvm-project/clang/test/CodeGenCXX/aarch64-arguments.cpp
new file mode 100644
index 0000000..013051c
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/aarch64-arguments.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -triple arm64-none-linux -emit-llvm -w -o - %s | FileCheck -check-prefix=PCS %s
+
+// PCS: define void @{{.*}}(i8 %a
+struct s0 {};
+void f0(s0 a) {}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/aarch64-cxxabi.cpp b/src/llvm-project/clang/test/CodeGenCXX/aarch64-cxxabi.cpp
new file mode 100644
index 0000000..6c08ff2
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/aarch64-cxxabi.cpp
@@ -0,0 +1,96 @@
+// RUN: %clang_cc1 -triple arm64-none-linux-gnu -emit-llvm -w -o - %s | FileCheck %s
+
+// Check differences between the generic Itanium ABI, the AArch32 version and
+// the AArch64 version.
+
+////////////////////////////////////////////////////////////////////////////////
+
+// The ABI says that the key function is the "textually first, non-inline,
+// non-pure, virtual member function". The generic version decides this after
+// the completion of the class definition; the AArch32 version decides this at
+// the end of the translation unit.
+
+// We construct a class which needs a VTable here under generic ABI, but not
+// AArch32.
+
+// (see next section for explanation of guard)
+// CHECK: @_ZGVZ15guard_variablesiE4mine = internal global i64 0
+
+// CHECK: @_ZTV16CheckKeyFunction =
+struct CheckKeyFunction {
+ virtual void foo();
+};
+
+// This is not inline when CheckKeyFunction is completed, so
+// CheckKeyFunction::foo is the key function. VTables should be emitted.
+inline void CheckKeyFunction::foo() {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+// Guard variables only specify and use the low bit to determine status, rather
+// than the low byte as in the generic Itanium ABI. However, unlike 32-bit ARM,
+// they *are* 64-bits wide so check that in case confusion has occurred.
+
+class Guarded {
+public:
+ Guarded(int i);
+ ~Guarded();
+};
+
+void guard_variables(int a) {
+ static Guarded mine(a);
+// CHECK: [[GUARDBIT:%[0-9]+]] = and i8 {{%[0-9]+}}, 1
+// CHECK: icmp eq i8 [[GUARDBIT]], 0
+
+ // As guards are 64-bit, these helpers should take 64-bit pointers.
+// CHECK: call i32 @__cxa_guard_acquire(i64*
+// CHECK: call void @__cxa_guard_release(i64*
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+// Member function pointers use the adj field to distinguish between virtual and
+// nonvirtual members. As a result the adjustment is shifted (if ptr was used, a
+// mask would be expected instead).
+
+class C {
+ int a();
+ virtual int b();
+};
+
+
+int member_pointer(C &c, int (C::*func)()) {
+// CHECK: ashr i64 %[[MEMPTRADJ:[0-9a-z.]+]], 1
+// CHECK: %[[ISVIRTUAL:[0-9]+]] = and i64 %[[MEMPTRADJ]], 1
+// CHECK: icmp ne i64 %[[ISVIRTUAL]], 0
+ return (c.*func)();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+// AArch64 PCS says that va_list type is based on "struct __va_list ..." in the
+// std namespace, which means it should mangle as "St9__va_list".
+
+// CHECK: @_Z7va_funcSt9__va_list
+void va_func(__builtin_va_list l) {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+// AArch64 constructors (like generic Itanium, but unlike AArch32) do not return
+// "this".
+
+void test_constructor() {
+ Guarded g(42);
+// CHECK: call void @_ZN7GuardedC1Ei
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+// In principle the AArch32 ABI allows this to be accomplished via a call to
+// __aeabi_atexit instead of __cxa_atexit. Clang doesn't make use of this at the
+// moment, but it's definitely not allowed for AArch64.
+
+// CHECK: call i32 @__cxa_atexit
+Guarded g(42);
diff --git a/src/llvm-project/clang/test/CodeGenCXX/aarch64-mangle-neon-vectors.cpp b/src/llvm-project/clang/test/CodeGenCXX/aarch64-mangle-neon-vectors.cpp
new file mode 100644
index 0000000..3b4a309
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/aarch64-mangle-neon-vectors.cpp
@@ -0,0 +1,84 @@
+// RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon %s -emit-llvm -o - | FileCheck %s
+
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef signed char int8_t;
+typedef signed short int16_t;
+typedef signed long int64_t;
+typedef unsigned long uint64_t;
+typedef unsigned char poly8_t;
+typedef unsigned short poly16_t;
+typedef __fp16 float16_t;
+typedef float float32_t;
+typedef double float64_t;
+
+typedef __attribute__((neon_vector_type(8))) int8_t int8x8_t;
+typedef __attribute__((neon_vector_type(16))) int8_t int8x16_t;
+typedef __attribute__((neon_vector_type(4))) int16_t int16x4_t;
+typedef __attribute__((neon_vector_type(8))) int16_t int16x8_t;
+typedef __attribute__((neon_vector_type(2))) int int32x2_t;
+typedef __attribute__((neon_vector_type(4))) int int32x4_t;
+typedef __attribute__((neon_vector_type(2))) int64_t int64x2_t;
+typedef __attribute__((neon_vector_type(8))) uint8_t uint8x8_t;
+typedef __attribute__((neon_vector_type(16))) uint8_t uint8x16_t;
+typedef __attribute__((neon_vector_type(4))) uint16_t uint16x4_t;
+typedef __attribute__((neon_vector_type(8))) uint16_t uint16x8_t;
+typedef __attribute__((neon_vector_type(2))) unsigned int uint32x2_t;
+typedef __attribute__((neon_vector_type(4))) unsigned int uint32x4_t;
+typedef __attribute__((neon_vector_type(2))) uint64_t uint64x2_t;
+typedef __attribute__((neon_vector_type(4))) float16_t float16x4_t;
+typedef __attribute__((neon_vector_type(8))) float16_t float16x8_t;
+typedef __attribute__((neon_vector_type(2))) float32_t float32x2_t;
+typedef __attribute__((neon_vector_type(4))) float32_t float32x4_t;
+typedef __attribute__((neon_vector_type(2))) float64_t float64x2_t;
+typedef __attribute__((neon_polyvector_type(8))) poly8_t poly8x8_t;
+typedef __attribute__((neon_polyvector_type(16))) poly8_t poly8x16_t;
+typedef __attribute__((neon_polyvector_type(4))) poly16_t poly16x4_t;
+typedef __attribute__((neon_polyvector_type(8))) poly16_t poly16x8_t;
+
+// CHECK: 10__Int8x8_t
+void f1(int8x8_t) {}
+// CHECK: 11__Int16x4_t
+void f2(int16x4_t) {}
+// CHECK: 11__Int32x2_t
+void f3(int32x2_t) {}
+// CHECK: 11__Uint8x8_t
+void f4(uint8x8_t) {}
+// CHECK: 12__Uint16x4_t
+void f5(uint16x4_t) {}
+// CHECK: 13__Float16x4_t
+void f6(float16x4_t) {}
+// CHECK: 13__Float16x8_t
+void f7(float16x8_t) {}
+// CHECK: 12__Uint32x2_t
+void f8(uint32x2_t) {}
+// CHECK: 13__Float32x2_t
+void f9(float32x2_t) {}
+// CHECK: 13__Float32x4_t
+void f10(float32x4_t) {}
+// CHECK: 11__Poly8x8_t
+void f11(poly8x8_t v) {}
+// CHECK: 12__Poly16x4_t
+void f12(poly16x4_t v) {}
+// CHECK:12__Poly8x16_t
+void f13(poly8x16_t v) {}
+// CHECK:12__Poly16x8_t
+void f14(poly16x8_t v) {}
+// CHECK: 11__Int8x16_t
+void f15(int8x16_t) {}
+// CHECK: 11__Int16x8_t
+void f16(int16x8_t) {}
+// CHECK:11__Int32x4_t
+void f17(int32x4_t) {}
+// CHECK: 12__Uint8x16_t
+void f18(uint8x16_t) {}
+// CHECK: 12__Uint16x8_t
+void f19(uint16x8_t) {}
+// CHECK: 12__Uint32x4_t
+void f20(uint32x4_t) {}
+// CHECK: 11__Int64x2_t
+void f21(int64x2_t) {}
+// CHECK: 12__Uint64x2_t
+void f22(uint64x2_t) {}
+// CHECK: 13__Float64x2_t
+void f23(float64x2_t) {}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/aarch64-neon.cpp b/src/llvm-project/clang/test/CodeGenCXX/aarch64-neon.cpp
new file mode 100644
index 0000000..fc8642d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/aarch64-neon.cpp
@@ -0,0 +1,15 @@
+// REQUIRES: aarch64-registered-target
+// RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \
+// RUN: -ffp-contract=fast -S -O3 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-none-netbsd-gnu -target-feature +neon \
+// RUN: -ffp-contract=fast -S -O3 -o - %s | FileCheck %s
+
+// Test whether arm_neon.h works as expected in C++.
+
+#include "arm_neon.h"
+
+poly64x1_t test_vld1_p64(poly64_t const * ptr) {
+ // CHECK: test_vld1_p64
+ return vld1_p64(ptr);
+ // CHECK: {{ld1 { v[0-9]+.1d }|ldr d[0-9]+}}, [{{x[0-9]+|sp}}]
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/aarch64-sign-return-address-static-ctor.cpp b/src/llvm-project/clang/test/CodeGenCXX/aarch64-sign-return-address-static-ctor.cpp
new file mode 100644
index 0000000..3971c22
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/aarch64-sign-return-address-static-ctor.cpp
@@ -0,0 +1,41 @@
+// RUN: %clang -target aarch64-arm-none-eabi -S -emit-llvm -o - -msign-return-address=none %s | \
+// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NONE
+// RUN: %clang -target aarch64-arm-none-eabi -S -emit-llvm -o - -msign-return-address=non-leaf %s | \
+// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-PARTIAL --check-prefix=CHECK-A-KEY
+// RUN: %clang -target aarch64-arm-none-eabi -S -emit-llvm -o - -msign-return-address=all %s | \
+// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ALL --check-prefix=CHECK-A-KEY
+
+// RUN: %clang -target aarch64-arm-none-eabi -S -emit-llvm -o - -mbranch-protection=none %s | \
+// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NONE
+// RUN: %clang -target aarch64-arm-none-eabi -S -emit-llvm -o - -mbranch-protection=standard %s | \
+// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-PARTIAL --check-prefix=CHECK-A-KEY --check-prefix=CHECK-BTE
+// RUN: %clang -target aarch64-arm-none-eabi -S -emit-llvm -o - -mbranch-protection=pac-ret %s | \
+// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-PARTIAL --check-prefix=CHECK-A-KEY
+// RUN: %clang -target aarch64-arm-none-eabi -S -emit-llvm -o - -mbranch-protection=pac-ret+leaf %s | \
+// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ALL --check-prefix=CHECK-A-KEY
+// RUN: %clang -target aarch64-arm-none-eabi -S -emit-llvm -o - -mbranch-protection=pac-ret+b-key %s | \
+// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-PARTIAL --check-prefix=CHECK-B-KEY
+// RUN: %clang -target aarch64-arm-none-eabi -S -emit-llvm -o - -mbranch-protection=pac-ret+b-key+leaf %s | \
+// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ALL --check-prefix=CHECK-B-KEY
+// RUN: %clang -target aarch64-arm-none-eabi -S -emit-llvm -o - -mbranch-protection=bti %s | \
+// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-BTE
+// RUN: %clang -target aarch64-arm-none-eabi -S -emit-llvm -o - -mbranch-protection=pac-ret+b-key+leaf+bti %s | \
+// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ALL --check-prefix=CHECK-B-KEY --check-prefix=BTE
+
+struct Foo {
+ Foo() {}
+ ~Foo() {}
+};
+
+Foo f;
+
+// CHECK: @llvm.global_ctors {{.*}}i32 65535, void ()* @[[CTOR_FN:.*]], i8* null
+
+// CHECK: @[[CTOR_FN]]() #[[ATTR:[0-9]*]]
+
+// CHECK-NONE-NOT: "sign-return-address"={{.*}}
+// CHECK-PARTIAL: "sign-return-address"="non-leaf"
+// CHECK-ALL: "sign-return-address"="all"
+// CHECK-A-KEY: "sign-return-address-key"="a_key"
+// CHECK-B-KEY: "sign-return-address-key"="b_key"
+// CHECK-BTE: "branch-target-enforcement"
diff --git a/src/llvm-project/clang/test/CodeGenCXX/abstract-class-ctors-dtors.cpp b/src/llvm-project/clang/test/CodeGenCXX/abstract-class-ctors-dtors.cpp
new file mode 100644
index 0000000..f1d2076
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/abstract-class-ctors-dtors.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+// Check that we don't emit the complete constructor/destructor for this class.
+struct A {
+ virtual void f() = 0;
+ A();
+ ~A();
+};
+
+// CHECK-NOT: define void @_ZN1AC1Ev
+// CHECK-LABEL: define void @_ZN1AC2Ev
+// CHECK-LABEL: define void @_ZN1AD2Ev
+// CHECK-LABEL: define void @_ZN1AD1Ev
+A::A() { }
+
+A::~A() { }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/address-of-fntemplate.cpp b/src/llvm-project/clang/test/CodeGenCXX/address-of-fntemplate.cpp
new file mode 100644
index 0000000..4840fe8
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/address-of-fntemplate.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 %s -emit-llvm -triple %itanium_abi_triple -o - | FileCheck %s
+template <typename T> void f(T) {}
+template <typename T> void f() { }
+
+void test() {
+ // CHECK: @_Z1fIiEvT_
+ void (*p)(int) = &f;
+
+ // CHECK: @_Z1fIiEvv
+ void (*p2)() = f<int>;
+}
+// CHECK-LABEL: define linkonce_odr {{.*}}void @_Z1fIiEvT_
+// CHECK-LABEL: define linkonce_odr {{.*}}void @_Z1fIiEvv
+
+namespace PR6973 {
+ template<typename T>
+ struct X {
+ void f(const T&);
+ };
+
+ template<typename T>
+ int g();
+
+ void h(X<int (*)()> xf) {
+ xf.f(&g<int>);
+ }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/address-space-cast-coerce.cpp b/src/llvm-project/clang/test/CodeGenCXX/address-space-cast-coerce.cpp
new file mode 100644
index 0000000..940a4f5
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/address-space-cast-coerce.cpp
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 %s -triple=amdgcn-amd-amdhsa -emit-llvm -o - | FileCheck %s
+
+template<typename T, unsigned int n> struct my_vector_base;
+
+ template<typename T>
+ struct my_vector_base<T, 1> {
+ typedef T Native_vec_ __attribute__((ext_vector_type(1)));
+
+ union {
+ Native_vec_ data;
+ struct {
+ T x;
+ };
+ };
+ };
+
+ template<typename T, unsigned int rank>
+ struct my_vector_type : public my_vector_base<T, rank> {
+ using my_vector_base<T, rank>::data;
+ using typename my_vector_base<T, rank>::Native_vec_;
+
+ template< typename U>
+ my_vector_type(U x) noexcept
+ {
+ for (auto i = 0u; i != rank; ++i) data[i] = x;
+ }
+ my_vector_type& operator+=(const my_vector_type& x) noexcept
+ {
+ data += x.data;
+ return *this;
+ }
+ };
+
+template<typename T, unsigned int n>
+ inline
+ my_vector_type<T, n> operator+(
+ const my_vector_type<T, n>& x, const my_vector_type<T, n>& y) noexcept
+ {
+ return my_vector_type<T, n>{x} += y;
+ }
+
+using char1 = my_vector_type<char, 1>;
+
+int mane() {
+
+ char1 f1{1};
+ char1 f2{1};
+
+// CHECK: %[[a:[^ ]+]] = addrspacecast i16 addrspace(5)* %{{[^ ]+}} to i16*
+// CHECK: %[[a:[^ ]+]] = addrspacecast %{{[^ ]+}} addrspace(5)* %{{[^ ]+}} to %{{[^ ]+}}
+
+ char1 f3 = f1 + f2;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/address-space-cast.cpp b/src/llvm-project/clang/test/CodeGenCXX/address-space-cast.cpp
new file mode 100644
index 0000000..e0cf3c1
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/address-space-cast.cpp
@@ -0,0 +1,65 @@
+// RUN: %clang_cc1 %s -triple=amdgcn-amd-amdhsa -emit-llvm -o - | FileCheck %s
+
+#define __private__ __attribute__((address_space(5)))
+
+void func_pchar(__private__ char *x);
+void func_pvoid(__private__ void *x);
+void func_pint(__private__ int *x);
+
+void test_cast(char *gen_char_ptr, void *gen_void_ptr, int *gen_int_ptr) {
+ // CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i8 addrspace(5)*
+ // CHECK-NEXT: store i8 addrspace(5)* %[[cast]]
+ __private__ char *priv_char_ptr = (__private__ char *)gen_char_ptr;
+
+ // CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i8 addrspace(5)*
+ // CHECK-NEXT: store i8 addrspace(5)* %[[cast]]
+ priv_char_ptr = (__private__ char *)gen_void_ptr;
+
+ // CHECK: %[[cast:.*]] = addrspacecast i32* %{{.*}} to i8 addrspace(5)*
+ // CHECK-NEXT: store i8 addrspace(5)* %[[cast]]
+ priv_char_ptr = (__private__ char *)gen_int_ptr;
+
+ // CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i8 addrspace(5)*
+ // CHECK-NEXT: store i8 addrspace(5)* %[[cast]]
+ __private__ void *priv_void_ptr = (__private__ void *)gen_char_ptr;
+
+ // CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i8 addrspace(5)*
+ // CHECK-NEXT: store i8 addrspace(5)* %[[cast]]
+ priv_void_ptr = (__private__ void *)gen_void_ptr;
+
+ // CHECK: %[[cast:.*]] = addrspacecast i32* %{{.*}} to i8 addrspace(5)*
+ // CHECK-NEXT: store i8 addrspace(5)* %[[cast]]
+ priv_void_ptr = (__private__ void *)gen_int_ptr;
+
+ // CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i32 addrspace(5)*
+ // CHECK-NEXT: store i32 addrspace(5)* %[[cast]]
+ __private__ int *priv_int_ptr = (__private__ int *)gen_void_ptr;
+
+ // CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i8 addrspace(5)*
+ // CHECK-NEXT: call void @_Z10func_pcharPU3AS5c(i8 addrspace(5)* %[[cast]])
+ func_pchar((__private__ char *)gen_char_ptr);
+
+ // CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i8 addrspace(5)*
+ // CHECK-NEXT: call void @_Z10func_pcharPU3AS5c(i8 addrspace(5)* %[[cast]])
+ func_pchar((__private__ char *)gen_void_ptr);
+
+ // CHECK: %[[cast:.*]] = addrspacecast i32* %{{.*}} to i8 addrspace(5)*
+ // CHECK-NEXT: call void @_Z10func_pcharPU3AS5c(i8 addrspace(5)* %[[cast]])
+ func_pchar((__private__ char *)gen_int_ptr);
+
+ // CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i8 addrspace(5)*
+ // CHECK-NEXT: call void @_Z10func_pvoidPU3AS5v(i8 addrspace(5)* %[[cast]])
+ func_pvoid((__private__ void *)gen_char_ptr);
+
+ // CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i8 addrspace(5)*
+ // CHECK-NEXT: call void @_Z10func_pvoidPU3AS5v(i8 addrspace(5)* %[[cast]])
+ func_pvoid((__private__ void *)gen_void_ptr);
+
+ // CHECK: %[[cast:.*]] = addrspacecast i32* %{{.*}} to i8 addrspace(5)*
+ // CHECK-NEXT: call void @_Z10func_pvoidPU3AS5v(i8 addrspace(5)* %[[cast]])
+ func_pvoid((__private__ void *)gen_int_ptr);
+
+ // CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i32 addrspace(5)*
+ // CHECK-NEXT: call void @_Z9func_pintPU3AS5i(i32 addrspace(5)* %[[cast]])
+ func_pint((__private__ int *)gen_void_ptr);
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/address-space-ref.cpp b/src/llvm-project/clang/test/CodeGenCXX/address-space-ref.cpp
new file mode 100644
index 0000000..5f0a429
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/address-space-ref.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s -check-prefixes=CHECK,NULL-INVALID
+// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-apple-darwin10 -fno-delete-null-pointer-checks -emit-llvm -o - | FileCheck %s -check-prefixes=CHECK,NULL-VALID
+
+// For a reference to a complete type, output the dereferenceable attribute (in
+// any address space).
+
+typedef int a __attribute__((address_space(1)));
+
+a & foo(a &x, a & y) {
+ return x;
+}
+
+// CHECK: define dereferenceable(4) i32 addrspace(1)* @_Z3fooRU3AS1iS0_(i32 addrspace(1)* dereferenceable(4) %x, i32 addrspace(1)* dereferenceable(4) %y)
+
+// For a reference to an incomplete type in an alternate address space, output
+// neither dereferenceable nor nonnull.
+
+class bc;
+typedef bc b __attribute__((address_space(1)));
+
+b & bar(b &x, b & y) {
+ return x;
+}
+
+// CHECK: define %class.bc addrspace(1)* @_Z3barRU3AS12bcS1_(%class.bc addrspace(1)* %x, %class.bc addrspace(1)* %y)
+
+// For a reference to an incomplete type in addrspace(0), output nonnull.
+
+bc & bar2(bc &x, bc & y) {
+ return x;
+}
+
+// NULL-INVALID: define nonnull %class.bc* @_Z4bar2R2bcS0_(%class.bc* nonnull %x, %class.bc* nonnull %y)
+// NULL-VALID: define %class.bc* @_Z4bar2R2bcS0_(%class.bc* %x, %class.bc* %y)
+
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/alias-available-externally.cpp b/src/llvm-project/clang/test/CodeGenCXX/alias-available-externally.cpp
new file mode 100644
index 0000000..473e93b
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/alias-available-externally.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -O1 -std=c++11 -emit-llvm -triple %itanium_abi_triple -disable-llvm-passes -o - %s | FileCheck %s
+// Clang should not generate alias to available_externally definitions.
+// Check that the destructor of Foo is defined.
+// The destructors have different return type for different targets.
+// CHECK: define linkonce_odr {{.*}} @_ZN3FooD2Ev
+template <class CharT>
+struct String {
+ String() {}
+ ~String();
+};
+
+template <class CharT>
+inline __attribute__((visibility("hidden"), always_inline))
+String<CharT>::~String() {}
+
+extern template struct String<char>;
+
+struct Foo : public String<char> { Foo() { String<char> s; } };
+
+Foo f;
diff --git a/src/llvm-project/clang/test/CodeGenCXX/align-avx-complete-objects.cpp b/src/llvm-project/clang/test/CodeGenCXX/align-avx-complete-objects.cpp
new file mode 100644
index 0000000..ad4a914
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/align-avx-complete-objects.cpp
@@ -0,0 +1,57 @@
+// RUN: %clang_cc1 -x c++ %s -O0 -triple=x86_64-apple-darwin -target-feature +avx2 -fmax-type-align=16 -emit-llvm -o - -Werror | FileCheck %s
+// rdar://16254558
+
+typedef float AVX2Float __attribute__((__vector_size__(32)));
+
+
+volatile float TestAlign(void)
+{
+ volatile AVX2Float *p = new AVX2Float;
+ *p = *p;
+ AVX2Float r = *p;
+ return r[0];
+}
+
+// CHECK: [[R:%.*]] = alloca <8 x float>, align 32
+// CHECK-NEXT: [[CALL:%.*]] = call i8* @_Znwm(i64 32)
+// CHECK-NEXT: [[ZERO:%.*]] = bitcast i8* [[CALL]] to <8 x float>*
+// CHECK-NEXT: store <8 x float>* [[ZERO]], <8 x float>** [[P:%.*]], align 8
+// CHECK-NEXT: [[ONE:%.*]] = load <8 x float>*, <8 x float>** [[P]], align 8
+// CHECK-NEXT: [[TWO:%.*]] = load volatile <8 x float>, <8 x float>* [[ONE]], align 16
+// CHECK-NEXT: [[THREE:%.*]] = load <8 x float>*, <8 x float>** [[P]], align 8
+// CHECK-NEXT: store volatile <8 x float> [[TWO]], <8 x float>* [[THREE]], align 16
+// CHECK-NEXT: [[FOUR:%.*]] = load <8 x float>*, <8 x float>** [[P]], align 8
+// CHECK-NEXT: [[FIVE:%.*]] = load volatile <8 x float>, <8 x float>* [[FOUR]], align 16
+// CHECK-NEXT: store <8 x float> [[FIVE]], <8 x float>* [[R]], align 32
+// CHECK-NEXT: [[SIX:%.*]] = load <8 x float>, <8 x float>* [[R]], align 32
+// CHECK-NEXT: [[VECEXT:%.*]] = extractelement <8 x float> [[SIX]], i32 0
+// CHECK-NEXT: ret float [[VECEXT]]
+
+typedef float AVX2Float_Explicitly_aligned __attribute__((__vector_size__(32))) __attribute__((aligned (32)));
+
+typedef AVX2Float_Explicitly_aligned AVX2Float_indirect;
+
+typedef AVX2Float_indirect AVX2Float_use_existing_align;
+
+volatile float TestAlign2(void)
+{
+ volatile AVX2Float_use_existing_align *p = new AVX2Float_use_existing_align;
+ *p = *p;
+ AVX2Float_use_existing_align r = *p;
+ return r[0];
+}
+
+// CHECK: [[R:%.*]] = alloca <8 x float>, align 32
+// CHECK-NEXT: [[CALL:%.*]] = call i8* @_Znwm(i64 32)
+// CHECK-NEXT: [[ZERO:%.*]] = bitcast i8* [[CALL]] to <8 x float>*
+// CHECK-NEXT: store <8 x float>* [[ZERO]], <8 x float>** [[P:%.*]], align 8
+// CHECK-NEXT: [[ONE:%.*]] = load <8 x float>*, <8 x float>** [[P]], align 8
+// CHECK-NEXT: [[TWO:%.*]] = load volatile <8 x float>, <8 x float>* [[ONE]], align 32
+// CHECK-NEXT: [[THREE:%.*]] = load <8 x float>*, <8 x float>** [[P]], align 8
+// CHECK-NEXT: store volatile <8 x float> [[TWO]], <8 x float>* [[THREE]], align 32
+// CHECK-NEXT: [[FOUR:%.*]] = load <8 x float>*, <8 x float>** [[P]], align 8
+// CHECK-NEXT: [[FIVE:%.*]] = load volatile <8 x float>, <8 x float>* [[FOUR]], align 32
+// CHECK-NEXT: store <8 x float> [[FIVE]], <8 x float>* [[R]], align 32
+// CHECK-NEXT: [[SIX:%.*]] = load <8 x float>, <8 x float>* [[R]], align 32
+// CHECK-NEXT: [[VECEXT:%.*]] = extractelement <8 x float> [[SIX]], i32 0
+// CHECK-NEXT: ret float [[VECEXT]]
diff --git a/src/llvm-project/clang/test/CodeGenCXX/alignment.cpp b/src/llvm-project/clang/test/CodeGenCXX/alignment.cpp
new file mode 100644
index 0000000..37509fc
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/alignment.cpp
@@ -0,0 +1,311 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=x86_64-apple-darwin10 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NOCOMPAT
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=x86_64-apple-darwin10 -fclang-abi-compat=6.0 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-V6COMPAT
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=x86_64-scei-ps4 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-V6COMPAT
+
+extern int int_source();
+extern void int_sink(int x);
+
+namespace test0 {
+ struct A {
+ int aField;
+ int bField;
+ };
+
+ struct B {
+ int onebit : 2;
+ int twobit : 6;
+ int intField;
+ };
+
+ struct __attribute__((packed, aligned(2))) C : A, B {
+ };
+
+ // These accesses should have alignment 4 because they're at offset 0
+ // in a reference with an assumed alignment of 4.
+ // CHECK-LABEL: @_ZN5test01aERNS_1BE
+ void a(B &b) {
+ // CHECK: [[CALL:%.*]] = call i32 @_Z10int_sourcev()
+ // CHECK: [[B_P:%.*]] = load [[B:%.*]]*, [[B]]**
+ // CHECK: [[FIELD_P:%.*]] = bitcast [[B]]* [[B_P]] to i8*
+ // CHECK: [[TRUNC:%.*]] = trunc i32 [[CALL]] to i8
+ // CHECK: [[OLD_VALUE:%.*]] = load i8, i8* [[FIELD_P]], align 4
+ // CHECK: [[T0:%.*]] = and i8 [[TRUNC]], 3
+ // CHECK: [[T1:%.*]] = and i8 [[OLD_VALUE]], -4
+ // CHECK: [[T2:%.*]] = or i8 [[T1]], [[T0]]
+ // CHECK: store i8 [[T2]], i8* [[FIELD_P]], align 4
+ b.onebit = int_source();
+
+ // CHECK: [[B_P:%.*]] = load [[B]]*, [[B]]**
+ // CHECK: [[FIELD_P:%.*]] = bitcast [[B]]* [[B_P]] to i8*
+ // CHECK: [[VALUE:%.*]] = load i8, i8* [[FIELD_P]], align 4
+ // CHECK: [[T0:%.*]] = shl i8 [[VALUE]], 6
+ // CHECK: [[T1:%.*]] = ashr i8 [[T0]], 6
+ // CHECK: [[T2:%.*]] = sext i8 [[T1]] to i32
+ // CHECK: call void @_Z8int_sinki(i32 [[T2]])
+ int_sink(b.onebit);
+ }
+
+ // These accesses should have alignment 2 because they're at offset 8
+ // in a reference/pointer with an assumed alignment of 2.
+ // CHECK-LABEL: @_ZN5test01bERNS_1CE
+ void b(C &c) {
+ // CHECK: [[CALL:%.*]] = call i32 @_Z10int_sourcev()
+ // CHECK: [[C_P:%.*]] = load [[C:%.*]]*, [[C]]**
+ // CHECK: [[T0:%.*]] = bitcast [[C]]* [[C_P]] to i8*
+ // CHECK: [[T1:%.*]] = getelementptr inbounds i8, i8* [[T0]], i64 8
+ // CHECK: [[B_P:%.*]] = bitcast i8* [[T1]] to [[B]]*
+ // CHECK: [[FIELD_P:%.*]] = bitcast [[B]]* [[B_P]] to i8*
+ // CHECK: [[TRUNC:%.*]] = trunc i32 [[CALL]] to i8
+ // CHECK-V6COMPAT: [[OLD_VALUE:%.*]] = load i8, i8* [[FIELD_P]], align 2
+ // CHECK-NOCOMPAT: [[OLD_VALUE:%.*]] = load i8, i8* [[FIELD_P]], align 4
+ // CHECK: [[T0:%.*]] = and i8 [[TRUNC]], 3
+ // CHECK: [[T1:%.*]] = and i8 [[OLD_VALUE]], -4
+ // CHECK: [[T2:%.*]] = or i8 [[T1]], [[T0]]
+ // CHECK-V6COMPAT: store i8 [[T2]], i8* [[FIELD_P]], align 2
+ // CHECK-NOCOMPAT: store i8 [[T2]], i8* [[FIELD_P]], align 4
+ c.onebit = int_source();
+
+ // CHECK: [[C_P:%.*]] = load [[C]]*, [[C]]**
+ // CHECK: [[T0:%.*]] = bitcast [[C]]* [[C_P]] to i8*
+ // CHECK: [[T1:%.*]] = getelementptr inbounds i8, i8* [[T0]], i64 8
+ // CHECK: [[B_P:%.*]] = bitcast i8* [[T1]] to [[B]]*
+ // CHECK: [[FIELD_P:%.*]] = bitcast [[B]]* [[B_P]] to i8*
+ // CHECK-V6COMPAT: [[VALUE:%.*]] = load i8, i8* [[FIELD_P]], align 2
+ // CHECK-NOCOMPAT: [[VALUE:%.*]] = load i8, i8* [[FIELD_P]], align 4
+ // CHECK: [[T0:%.*]] = shl i8 [[VALUE]], 6
+ // CHECK: [[T1:%.*]] = ashr i8 [[T0]], 6
+ // CHECK: [[T2:%.*]] = sext i8 [[T1]] to i32
+ // CHECK: call void @_Z8int_sinki(i32 [[T2]])
+ int_sink(c.onebit);
+ }
+
+ // CHECK-LABEL: @_ZN5test01cEPNS_1CE
+ void c(C *c) {
+ // CHECK: [[CALL:%.*]] = call i32 @_Z10int_sourcev()
+ // CHECK: [[C_P:%.*]] = load [[C]]*, [[C]]**
+ // CHECK: [[T0:%.*]] = bitcast [[C]]* [[C_P]] to i8*
+ // CHECK: [[T1:%.*]] = getelementptr inbounds i8, i8* [[T0]], i64 8
+ // CHECK: [[B_P:%.*]] = bitcast i8* [[T1]] to [[B]]*
+ // CHECK: [[FIELD_P:%.*]] = bitcast [[B]]* [[B_P]] to i8*
+ // CHECK: [[TRUNC:%.*]] = trunc i32 [[CALL]] to i8
+ // CHECK-V6COMPAT: [[OLD_VALUE:%.*]] = load i8, i8* [[FIELD_P]], align 2
+ // CHECK-NOCOMPAT: [[OLD_VALUE:%.*]] = load i8, i8* [[FIELD_P]], align 4
+ // CHECK: [[T0:%.*]] = and i8 [[TRUNC]], 3
+ // CHECK: [[T1:%.*]] = and i8 [[OLD_VALUE]], -4
+ // CHECK: [[T2:%.*]] = or i8 [[T1]], [[T0]]
+ // CHECK-V6COMPAT: store i8 [[T2]], i8* [[FIELD_P]], align 2
+ // CHECK-NOCOMPAT: store i8 [[T2]], i8* [[FIELD_P]], align 4
+ c->onebit = int_source();
+
+ // CHECK: [[C_P:%.*]] = load [[C:%.*]]*, [[C]]**
+ // CHECK: [[T0:%.*]] = bitcast [[C]]* [[C_P]] to i8*
+ // CHECK: [[T1:%.*]] = getelementptr inbounds i8, i8* [[T0]], i64 8
+ // CHECK: [[B_P:%.*]] = bitcast i8* [[T1]] to [[B:%.*]]*
+ // CHECK: [[FIELD_P:%.*]] = bitcast [[B]]* [[B_P]] to i8*
+ // CHECK-V6COMPAT: [[VALUE:%.*]] = load i8, i8* [[FIELD_P]], align 2
+ // CHECK-NOCOMPAT: [[VALUE:%.*]] = load i8, i8* [[FIELD_P]], align 4
+ // CHECK: [[T0:%.*]] = shl i8 [[VALUE]], 6
+ // CHECK: [[T1:%.*]] = ashr i8 [[T0]], 6
+ // CHECK: [[T2:%.*]] = sext i8 [[T1]] to i32
+ // CHECK: call void @_Z8int_sinki(i32 [[T2]])
+ int_sink(c->onebit);
+ }
+
+ // These accesses should have alignment 2 because they're at offset 8
+ // in an alignment-2 variable.
+ // CHECK-LABEL: @_ZN5test01dEv
+ void d() {
+ // CHECK-V6COMPAT: [[C_P:%.*]] = alloca [[C:%.*]], align 2
+ // CHECK-NOCOMPAT: [[C_P:%.*]] = alloca [[C:%.*]], align 4
+ C c;
+
+ // CHECK: [[CALL:%.*]] = call i32 @_Z10int_sourcev()
+ // CHECK: [[T0:%.*]] = bitcast [[C]]* [[C_P]] to i8*
+ // CHECK: [[T1:%.*]] = getelementptr inbounds i8, i8* [[T0]], i64 8
+ // CHECK: [[B_P:%.*]] = bitcast i8* [[T1]] to [[B]]*
+ // CHECK: [[FIELD_P:%.*]] = bitcast [[B]]* [[B_P]] to i8*
+ // CHECK: [[TRUNC:%.*]] = trunc i32 [[CALL]] to i8
+ // CHECK-V6COMPAT: [[OLD_VALUE:%.*]] = load i8, i8* [[FIELD_P]], align 2
+ // CHECK-NOCOMPAT: [[OLD_VALUE:%.*]] = load i8, i8* [[FIELD_P]], align 4
+ // CHECK: [[T0:%.*]] = and i8 [[TRUNC]], 3
+ // CHECK: [[T1:%.*]] = and i8 [[OLD_VALUE]], -4
+ // CHECK: [[T2:%.*]] = or i8 [[T1]], [[T0]]
+ // CHECK-V6COMPAT: store i8 [[T2]], i8* [[FIELD_P]], align 2
+ // CHECK-NOCOMPAT: store i8 [[T2]], i8* [[FIELD_P]], align 4
+ c.onebit = int_source();
+
+ // CHECK: [[T0:%.*]] = bitcast [[C]]* [[C_P]] to i8*
+ // CHECK: [[T1:%.*]] = getelementptr inbounds i8, i8* [[T0]], i64 8
+ // CHECK: [[B_P:%.*]] = bitcast i8* [[T1]] to [[B:%.*]]*
+ // CHECK: [[FIELD_P:%.*]] = bitcast [[B]]* [[B_P]] to i8*
+ // CHECK-V6COMPAT: [[VALUE:%.*]] = load i8, i8* [[FIELD_P]], align 2
+ // CHECK-NOCOMPAT: [[VALUE:%.*]] = load i8, i8* [[FIELD_P]], align 4
+ // CHECK: [[T0:%.*]] = shl i8 [[VALUE]], 6
+ // CHECK: [[T1:%.*]] = ashr i8 [[T0]], 6
+ // CHECK: [[T2:%.*]] = sext i8 [[T1]] to i32
+ // CHECK: call void @_Z8int_sinki(i32 [[T2]])
+ int_sink(c.onebit);
+ }
+
+ // These accesses should have alignment 8 because they're at offset 8
+ // in an alignment-16 variable.
+ // CHECK-LABEL: @_ZN5test01eEv
+ void e() {
+ // CHECK: [[C_P:%.*]] = alloca [[C:%.*]], align 16
+ __attribute__((aligned(16))) C c;
+
+ // CHECK: [[CALL:%.*]] = call i32 @_Z10int_sourcev()
+ // CHECK: [[T0:%.*]] = bitcast [[C]]* [[C_P]] to i8*
+ // CHECK: [[T1:%.*]] = getelementptr inbounds i8, i8* [[T0]], i64 8
+ // CHECK: [[B_P:%.*]] = bitcast i8* [[T1]] to [[B]]*
+ // CHECK: [[FIELD_P:%.*]] = bitcast [[B]]* [[B_P]] to i8*
+ // CHECK: [[TRUNC:%.*]] = trunc i32 [[CALL]] to i8
+ // CHECK: [[OLD_VALUE:%.*]] = load i8, i8* [[FIELD_P]], align 8
+ // CHECK: [[T0:%.*]] = and i8 [[TRUNC]], 3
+ // CHECK: [[T1:%.*]] = and i8 [[OLD_VALUE]], -4
+ // CHECK: [[T2:%.*]] = or i8 [[T1]], [[T0]]
+ // CHECK: store i8 [[T2]], i8* [[FIELD_P]], align 8
+ c.onebit = int_source();
+
+ // CHECK: [[T0:%.*]] = bitcast [[C]]* [[C_P]] to i8*
+ // CHECK: [[T1:%.*]] = getelementptr inbounds i8, i8* [[T0]], i64 8
+ // CHECK: [[B_P:%.*]] = bitcast i8* [[T1]] to [[B:%.*]]*
+ // CHECK: [[FIELD_P:%.*]] = bitcast [[B]]* [[B_P]] to i8*
+ // CHECK: [[VALUE:%.*]] = load i8, i8* [[FIELD_P]], align 8
+ // CHECK: [[T0:%.*]] = shl i8 [[VALUE]], 6
+ // CHECK: [[T1:%.*]] = ashr i8 [[T0]], 6
+ // CHECK: [[T2:%.*]] = sext i8 [[T1]] to i32
+ // CHECK: call void @_Z8int_sinki(i32 [[T2]])
+ int_sink(c.onebit);
+ }
+}
+
+namespace test1 {
+ struct Array {
+ int elts[4];
+ };
+
+ struct A {
+ __attribute__((aligned(16))) Array aArray;
+ };
+
+ struct B : virtual A {
+ void *bPointer; // puts bArray at offset 16
+ Array bArray;
+ };
+
+ struct C : virtual A { // must be viable as primary base
+ // Non-empty, nv-size not a multiple of 16.
+ void *cPointer1;
+ void *cPointer2;
+ };
+
+ // Proof of concept that the non-virtual components of B do not have
+ // to be 16-byte-aligned.
+ struct D : C, B {};
+
+ // For the following tests, we want to assign into a variable whose
+ // alignment is high enough that it will absolutely not be the
+ // constraint on the memcpy alignment.
+ typedef __attribute__((aligned(64))) Array AlignedArray;
+
+ // CHECK-LABEL: @_ZN5test11aERNS_1AE
+ void a(A &a) {
+ // CHECK: [[RESULT:%.*]] = alloca [[ARRAY:%.*]], align 64
+ // CHECK: [[A_P:%.*]] = load [[A:%.*]]*, [[A]]**
+ // CHECK: [[ARRAY_P:%.*]] = getelementptr inbounds [[A]], [[A]]* [[A_P]], i32 0, i32 0
+ // CHECK: [[T0:%.*]] = bitcast [[ARRAY]]* [[RESULT]] to i8*
+ // CHECK: [[T1:%.*]] = bitcast [[ARRAY]]* [[ARRAY_P]] to i8*
+ // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 64 [[T0]], i8* align 16 [[T1]], i64 16, i1 false)
+ AlignedArray result = a.aArray;
+ }
+
+ // CHECK-LABEL: @_ZN5test11bERNS_1BE
+ void b(B &b) {
+ // CHECK: [[RESULT:%.*]] = alloca [[ARRAY]], align 64
+ // CHECK: [[B_P:%.*]] = load [[B:%.*]]*, [[B]]**
+ // CHECK: [[VPTR_P:%.*]] = bitcast [[B]]* [[B_P]] to i8**
+ // CHECK: [[VPTR:%.*]] = load i8*, i8** [[VPTR_P]], align 8
+ // CHECK: [[T0:%.*]] = getelementptr i8, i8* [[VPTR]], i64 -24
+ // CHECK: [[OFFSET_P:%.*]] = bitcast i8* [[T0]] to i64*
+ // CHECK: [[OFFSET:%.*]] = load i64, i64* [[OFFSET_P]], align 8
+ // CHECK: [[T0:%.*]] = bitcast [[B]]* [[B_P]] to i8*
+ // CHECK: [[T1:%.*]] = getelementptr inbounds i8, i8* [[T0]], i64 [[OFFSET]]
+ // CHECK: [[A_P:%.*]] = bitcast i8* [[T1]] to [[A]]*
+ // CHECK: [[ARRAY_P:%.*]] = getelementptr inbounds [[A]], [[A]]* [[A_P]], i32 0, i32 0
+ // CHECK: [[T0:%.*]] = bitcast [[ARRAY]]* [[RESULT]] to i8*
+ // CHECK: [[T1:%.*]] = bitcast [[ARRAY]]* [[ARRAY_P]] to i8*
+ // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 64 [[T0]], i8* align 16 [[T1]], i64 16, i1 false)
+ AlignedArray result = b.aArray;
+ }
+
+ // CHECK-LABEL: @_ZN5test11cERNS_1BE
+ void c(B &b) {
+ // CHECK: [[RESULT:%.*]] = alloca [[ARRAY]], align 64
+ // CHECK: [[B_P:%.*]] = load [[B]]*, [[B]]**
+ // CHECK: [[ARRAY_P:%.*]] = getelementptr inbounds [[B]], [[B]]* [[B_P]], i32 0, i32 2
+ // CHECK: [[T0:%.*]] = bitcast [[ARRAY]]* [[RESULT]] to i8*
+ // CHECK: [[T1:%.*]] = bitcast [[ARRAY]]* [[ARRAY_P]] to i8*
+ // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 64 [[T0]], i8* align 8 [[T1]], i64 16, i1 false)
+ AlignedArray result = b.bArray;
+ }
+
+ // CHECK-LABEL: @_ZN5test11dEPNS_1BE
+ void d(B *b) {
+ // CHECK: [[RESULT:%.*]] = alloca [[ARRAY]], align 64
+ // CHECK: [[B_P:%.*]] = load [[B]]*, [[B]]**
+ // CHECK: [[ARRAY_P:%.*]] = getelementptr inbounds [[B]], [[B]]* [[B_P]], i32 0, i32 2
+ // CHECK: [[T0:%.*]] = bitcast [[ARRAY]]* [[RESULT]] to i8*
+ // CHECK: [[T1:%.*]] = bitcast [[ARRAY]]* [[ARRAY_P]] to i8*
+ // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 64 [[T0]], i8* align 8 [[T1]], i64 16, i1 false)
+ AlignedArray result = b->bArray;
+ }
+
+ // CHECK-LABEL: @_ZN5test11eEv
+ void e() {
+ // CHECK: [[B_P:%.*]] = alloca [[B]], align 16
+ // CHECK: [[RESULT:%.*]] = alloca [[ARRAY]], align 64
+ // CHECK: [[ARRAY_P:%.*]] = getelementptr inbounds [[B]], [[B]]* [[B_P]], i32 0, i32 2
+ // CHECK: [[T0:%.*]] = bitcast [[ARRAY]]* [[RESULT]] to i8*
+ // CHECK: [[T1:%.*]] = bitcast [[ARRAY]]* [[ARRAY_P]] to i8*
+ // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 64 [[T0]], i8* align 16 [[T1]], i64 16, i1 false)
+ B b;
+ AlignedArray result = b.bArray;
+ }
+
+ // CHECK-LABEL: @_ZN5test11fEv
+ void f() {
+ // TODO: we should devirtualize this derived-to-base conversion.
+ // CHECK: [[D_P:%.*]] = alloca [[D:%.*]], align 16
+ // CHECK: [[RESULT:%.*]] = alloca [[ARRAY]], align 64
+ // CHECK: [[VPTR_P:%.*]] = bitcast [[D]]* [[D_P]] to i8**
+ // CHECK: [[VPTR:%.*]] = load i8*, i8** [[VPTR_P]], align 16
+ // CHECK: [[T0:%.*]] = getelementptr i8, i8* [[VPTR]], i64 -24
+ // CHECK: [[OFFSET_P:%.*]] = bitcast i8* [[T0]] to i64*
+ // CHECK: [[OFFSET:%.*]] = load i64, i64* [[OFFSET_P]], align 8
+ // CHECK: [[T0:%.*]] = bitcast [[D]]* [[D_P]] to i8*
+ // CHECK: [[T1:%.*]] = getelementptr inbounds i8, i8* [[T0]], i64 [[OFFSET]]
+ // CHECK: [[A_P:%.*]] = bitcast i8* [[T1]] to [[A]]*
+ // CHECK: [[ARRAY_P:%.*]] = getelementptr inbounds [[A]], [[A]]* [[A_P]], i32 0, i32 0
+ // CHECK: [[T0:%.*]] = bitcast [[ARRAY]]* [[RESULT]] to i8*
+ // CHECK: [[T1:%.*]] = bitcast [[ARRAY]]* [[ARRAY_P]] to i8*
+ // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 64 [[T0]], i8* align 16 [[T1]], i64 16, i1 false)
+ D d;
+ AlignedArray result = d.aArray;
+ }
+
+ // CHECK-LABEL: @_ZN5test11gEv
+ void g() {
+ // CHECK: [[D_P:%.*]] = alloca [[D]], align 16
+ // CHECK: [[RESULT:%.*]] = alloca [[ARRAY]], align 64
+ // CHECK: [[T0:%.*]] = bitcast [[D]]* [[D_P]] to i8*
+ // CHECK: [[T1:%.*]] = getelementptr inbounds i8, i8* [[T0]], i64 24
+ // CHECK: [[B_P:%.*]] = bitcast i8* [[T1]] to [[B:%.*]]*
+ // CHECK: [[ARRAY_P:%.*]] = getelementptr inbounds [[B]], [[B]]* [[B_P]], i32 0, i32 2
+ // CHECK: [[T0:%.*]] = bitcast [[ARRAY]]* [[RESULT]] to i8*
+ // CHECK: [[T1:%.*]] = bitcast [[ARRAY]]* [[ARRAY_P]] to i8*
+ // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 64 [[T0]], i8* align 8 [[T1]], i64 16, i1 false)
+ D d;
+ AlignedArray result = d.bArray;
+ }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/alloc-size.cpp b/src/llvm-project/clang/test/CodeGenCXX/alloc-size.cpp
new file mode 100644
index 0000000..e68e52c
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/alloc-size.cpp
@@ -0,0 +1,106 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -O0 %s -o - 2>&1 -std=c++11 | FileCheck %s
+
+namespace templates {
+void *my_malloc(int N) __attribute__((alloc_size(1)));
+void *my_calloc(int N, int M) __attribute__((alloc_size(1, 2)));
+
+struct MyType {
+ int arr[4];
+};
+
+template <typename T> int callMalloc();
+
+template <typename T, int N> int callCalloc();
+
+// CHECK-LABEL: define i32 @_ZN9templates6testItEv()
+int testIt() {
+ // CHECK: call i32 @_ZN9templates10callMallocINS_6MyTypeEEEiv
+ // CHECK: call i32 @_ZN9templates10callCallocINS_6MyTypeELi4EEEiv
+ return callMalloc<MyType>() + callCalloc<MyType, 4>();
+}
+
+// CHECK-LABEL: define linkonce_odr i32
+// @_ZN9templates10callMallocINS_6MyTypeEEEiv
+template <typename T> int callMalloc() {
+ static_assert(sizeof(T) == 16, "");
+ // CHECK: ret i32 16
+ return __builtin_object_size(my_malloc(sizeof(T)), 0);
+}
+
+// CHECK-LABEL: define linkonce_odr i32
+// @_ZN9templates10callCallocINS_6MyTypeELi4EEEiv
+template <typename T, int N> int callCalloc() {
+ static_assert(sizeof(T) * N == 64, "");
+ // CHECK: ret i32 64
+ return __builtin_object_size(my_malloc(sizeof(T) * N), 0);
+}
+}
+
+namespace templated_alloc_size {
+using size_t = unsigned long;
+
+// We don't need bodies for any of these, because they're only used in
+// __builtin_object_size, and that shouldn't need anything but a function
+// decl with alloc_size on it.
+template <typename T>
+T *my_malloc(size_t N = sizeof(T)) __attribute__((alloc_size(1)));
+
+template <typename T>
+T *my_calloc(size_t M, size_t N = sizeof(T)) __attribute__((alloc_size(2, 1)));
+
+template <size_t N>
+void *dependent_malloc(size_t NT = N) __attribute__((alloc_size(1)));
+
+template <size_t N, size_t M>
+void *dependent_calloc(size_t NT = N, size_t MT = M)
+ __attribute__((alloc_size(1, 2)));
+
+template <typename T, size_t M>
+void *dependent_calloc2(size_t NT = sizeof(T), size_t MT = M)
+ __attribute__((alloc_size(1, 2)));
+
+// CHECK-LABEL: define i32 @_ZN20templated_alloc_size6testItEv
+int testIt() {
+ // 122 = 4 + 5*4 + 6 + 7*8 + 4*9
+ // CHECK: ret i32 122
+ return __builtin_object_size(my_malloc<int>(), 0) +
+ __builtin_object_size(my_calloc<int>(5), 0) +
+ __builtin_object_size(dependent_malloc<6>(), 0) +
+ __builtin_object_size(dependent_calloc<7, 8>(), 0) +
+ __builtin_object_size(dependent_calloc2<int, 9>(), 0);
+}
+} // namespace templated_alloc_size
+
+// Be sure that an ExprWithCleanups doesn't deter us.
+namespace alloc_size_with_cleanups {
+struct Foo {
+ ~Foo();
+};
+
+void *my_malloc(const Foo &, int N) __attribute__((alloc_size(2)));
+
+// CHECK-LABEL: define i32 @_ZN24alloc_size_with_cleanups6testItEv
+int testIt() {
+ int *const p = (int *)my_malloc(Foo{}, 3);
+ // CHECK: ret i32 3
+ return __builtin_object_size(p, 0);
+}
+} // namespace alloc_size_with_cleanups
+
+class C {
+public:
+ void *my_malloc(int N) __attribute__((alloc_size(2)));
+ void *my_calloc(int N, int M) __attribute__((alloc_size(2, 3)));
+};
+
+// CHECK-LABEL: define i32 @_Z16callMemberMallocv
+int callMemberMalloc() {
+ // CHECK: ret i32 16
+ return __builtin_object_size(C().my_malloc(16), 0);
+}
+
+// CHECK-LABEL: define i32 @_Z16callMemberCallocv
+int callMemberCalloc() {
+ // CHECK: ret i32 32
+ return __builtin_object_size(C().my_calloc(16, 2), 0);
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/alloca-align.cpp b/src/llvm-project/clang/test/CodeGenCXX/alloca-align.cpp
new file mode 100644
index 0000000..079b55d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/alloca-align.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s
+
+struct s0 {
+ int Start, End;
+ unsigned Alignment;
+ int TheStores __attribute__((aligned(16)));
+};
+
+// CHECK-LABEL: define void @f0
+// CHECK: alloca %struct.s0, align 16
+extern "C" void f0() {
+ (void) s0();
+}
+
+// CHECK-LABEL: define void @f1
+// CHECK: alloca %struct.s0, align 16
+extern "C" void f1() {
+ (void) (struct s0) { 0, 0, 0, 0 };
+}
+
+// CHECK-LABEL: define i32 @f2
+// CHECK: alloca %struct.s1, align 2
+struct s1 { short x; short y; };
+extern "C" struct s1 f2(int a, struct s1 *x, struct s1 *y) {
+ if (a)
+ return *x;
+ return *y;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/always_destroy.cpp b/src/llvm-project/clang/test/CodeGenCXX/always_destroy.cpp
new file mode 100644
index 0000000..e84c4cf
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/always_destroy.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 %s -fno-c++-static-destructors -emit-llvm -triple x86_64-apple-macosx10.13.0 -o - | FileCheck %s
+
+struct NonTrivial {
+ ~NonTrivial();
+};
+
+// CHECK-NOT: __cxa_atexit{{.*}}_ZN10NonTrivialD1Ev
+NonTrivial nt1;
+// CHECK-NOT: _tlv_atexit{{.*}}_ZN10NonTrivialD1Ev
+thread_local NonTrivial nt2;
+
+struct NonTrivial2 {
+ ~NonTrivial2();
+};
+
+// CHECK: __cxa_atexit{{.*}}_ZN11NonTrivial2D1Ev
+[[clang::always_destroy]] NonTrivial2 nt21;
+// CHECK: _tlv_atexit{{.*}}_ZN11NonTrivial2D1Ev
+[[clang::always_destroy]] thread_local NonTrivial2 nt22;
+
+void f() {
+ // CHECK: __cxa_atexit{{.*}}_ZN11NonTrivial2D1Ev
+ [[clang::always_destroy]] static NonTrivial2 nt21;
+ // CHECK: _tlv_atexit{{.*}}_ZN11NonTrivial2D1Ev
+ [[clang::always_destroy]] thread_local NonTrivial2 nt22;
+}
+
+// CHECK-NOT: __cxa_atexit{{.*}}_ZN10NonTrivialD1Ev
+[[clang::no_destroy]] NonTrivial nt3;
+// CHECK-NOT: _tlv_atexit{{.*}}_ZN10NonTrivialD1Ev
+[[clang::no_destroy]] thread_local NonTrivial nt4;
diff --git a/src/llvm-project/clang/test/CodeGenCXX/amdgcn-automatic-variable.cpp b/src/llvm-project/clang/test/CodeGenCXX/amdgcn-automatic-variable.cpp
new file mode 100644
index 0000000..9830a78
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/amdgcn-automatic-variable.cpp
@@ -0,0 +1,105 @@
+// RUN: %clang_cc1 -O0 -triple amdgcn---amdgiz -emit-llvm %s -o - | FileCheck %s
+
+// CHECK-LABEL: define void @_Z5func1Pi(i32* %x)
+void func1(int *x) {
+ // CHECK: %[[x_addr:.*]] = alloca i32*{{.*}}addrspace(5)
+ // CHECK: %[[r0:.*]] = addrspacecast i32* addrspace(5)* %[[x_addr]] to i32**
+ // CHECK: store i32* %x, i32** %[[r0]]
+ // CHECK: %[[r1:.*]] = load i32*, i32** %[[r0]]
+ // CHECK: store i32 1, i32* %[[r1]]
+ *x = 1;
+}
+
+// CHECK-LABEL: define void @_Z5func2v()
+void func2(void) {
+ // CHECK: %lv1 = alloca i32, align 4, addrspace(5)
+ // CHECK: %[[r0:.*]] = addrspacecast i32 addrspace(5)* %lv1 to i32*
+ // CHECK: %lv2 = alloca i32, align 4, addrspace(5)
+ // CHECK: %[[r1:.*]] = addrspacecast i32 addrspace(5)* %lv2 to i32*
+ // CHECK: %la = alloca [100 x i32], align 4, addrspace(5)
+ // CHECK: %[[r2:.*]] = addrspacecast [100 x i32] addrspace(5)* %la to [100 x i32]*
+ // CHECK: %lp1 = alloca i32*, align 8, addrspace(5)
+ // CHECK: %[[r3:.*]] = addrspacecast i32* addrspace(5)* %lp1 to i32**
+ // CHECK: %lp2 = alloca i32*, align 8, addrspace(5)
+ // CHECK: %[[r4:.*]] = addrspacecast i32* addrspace(5)* %lp2 to i32**
+ // CHECK: %lvc = alloca i32, align 4, addrspace(5)
+ // CHECK: %[[r5:.*]] = addrspacecast i32 addrspace(5)* %lvc to i32*
+
+ // CHECK: store i32 1, i32* %[[r0]]
+ int lv1;
+ lv1 = 1;
+ // CHECK: store i32 2, i32* %[[r1]]
+ int lv2 = 2;
+
+ // CHECK: %[[arrayidx:.*]] = getelementptr inbounds [100 x i32], [100 x i32]* %[[r2]], i64 0, i64 0
+ // CHECK: store i32 3, i32* %[[arrayidx]], align 4
+ int la[100];
+ la[0] = 3;
+
+ // CHECK: store i32* %[[r0]], i32** %[[r3]], align 8
+ int *lp1 = &lv1;
+
+ // CHECK: %[[arraydecay:.*]] = getelementptr inbounds [100 x i32], [100 x i32]* %[[r2]], i32 0, i32 0
+ // CHECK: store i32* %[[arraydecay]], i32** %[[r4]], align 8
+ int *lp2 = la;
+
+ // CHECK: call void @_Z5func1Pi(i32* %[[r0]])
+ func1(&lv1);
+
+ // CHECK: store i32 4, i32* %[[r5]]
+ // CHECK: store i32 4, i32* %[[r0]]
+ const int lvc = 4;
+ lv1 = lvc;
+}
+
+void destroy(int x);
+
+class A {
+int x;
+public:
+ A():x(0) {}
+ ~A() {
+ destroy(x);
+ }
+};
+
+// CHECK-LABEL: define void @_Z5func3v
+void func3() {
+ // CHECK: %[[a:.*]] = alloca %class.A, align 4, addrspace(5)
+ // CHECK: %[[r0:.*]] = addrspacecast %class.A addrspace(5)* %[[a]] to %class.A*
+ // CHECK: call void @_ZN1AC1Ev(%class.A* %[[r0]])
+ // CHECK: call void @_ZN1AD1Ev(%class.A* %[[r0]])
+ A a;
+}
+
+// CHECK-LABEL: define void @_Z5func4i
+void func4(int x) {
+ // CHECK: %[[x_addr:.*]] = alloca i32, align 4, addrspace(5)
+ // CHECK: %[[r0:.*]] = addrspacecast i32 addrspace(5)* %[[x_addr]] to i32*
+ // CHECK: store i32 %x, i32* %[[r0]], align 4
+ // CHECK: call void @_Z5func1Pi(i32* %[[r0]])
+ func1(&x);
+}
+
+// CHECK-LABEL: define void @_Z5func5v
+void func5() {
+ return;
+ int x = 0;
+}
+
+// CHECK-LABEL: define void @_Z5func6v
+void func6() {
+ return;
+ int x;
+}
+
+// CHECK-LABEL: define void @_Z5func7v
+extern void use(int *);
+void func7() {
+ goto later;
+ int x;
+later:
+ use(&x);
+}
+
+// CHECK-NOT: !opencl.ocl.version
diff --git a/src/llvm-project/clang/test/CodeGenCXX/amdgcn-func-arg.cpp b/src/llvm-project/clang/test/CodeGenCXX/amdgcn-func-arg.cpp
new file mode 100644
index 0000000..9ac143a
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/amdgcn-func-arg.cpp
@@ -0,0 +1,94 @@
+// RUN: %clang_cc1 -O0 -triple amdgcn -emit-llvm %s -o - | FileCheck %s
+
+class A {
+public:
+ int x;
+ A():x(0) {}
+ ~A() {}
+};
+
+class B {
+int x[100];
+};
+
+A g_a;
+B g_b;
+
+void func_with_ref_arg(A &a);
+void func_with_ref_arg(B &b);
+
+// CHECK-LABEL: define void @_Z22func_with_indirect_arg1A(%class.A addrspace(5)* %a)
+// CHECK: %p = alloca %class.A*, align 8, addrspace(5)
+// CHECK: %[[r1:.+]] = addrspacecast %class.A* addrspace(5)* %p to %class.A**
+// CHECK: %[[r0:.+]] = addrspacecast %class.A addrspace(5)* %a to %class.A*
+// CHECK: store %class.A* %[[r0]], %class.A** %[[r1]], align 8
+void func_with_indirect_arg(A a) {
+ A *p = &a;
+}
+
+// CHECK-LABEL: define void @_Z22test_indirect_arg_autov()
+// CHECK: %a = alloca %class.A, align 4, addrspace(5)
+// CHECK: %[[r0:.+]] = addrspacecast %class.A addrspace(5)* %a to %class.A*
+// CHECK: %agg.tmp = alloca %class.A, align 4, addrspace(5)
+// CHECK: %[[r1:.+]] = addrspacecast %class.A addrspace(5)* %agg.tmp to %class.A*
+// CHECK: call void @_ZN1AC1Ev(%class.A* %[[r0]])
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
+// CHECK: %[[r4:.+]] = addrspacecast %class.A* %[[r1]] to %class.A addrspace(5)*
+// CHECK: call void @_Z22func_with_indirect_arg1A(%class.A addrspace(5)* %[[r4]])
+// CHECK: call void @_ZN1AD1Ev(%class.A* %[[r1]])
+// CHECK: call void @_Z17func_with_ref_argR1A(%class.A* dereferenceable(4) %[[r0]])
+// CHECK: call void @_ZN1AD1Ev(%class.A* %[[r0]])
+void test_indirect_arg_auto() {
+ A a;
+ func_with_indirect_arg(a);
+ func_with_ref_arg(a);
+}
+
+// CHECK: define void @_Z24test_indirect_arg_globalv()
+// CHECK: %agg.tmp = alloca %class.A, align 4, addrspace(5)
+// CHECK: %[[r0:.+]] = addrspacecast %class.A addrspace(5)* %agg.tmp to %class.A*
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
+// CHECK: %[[r2:.+]] = addrspacecast %class.A* %[[r0]] to %class.A addrspace(5)*
+// CHECK: call void @_Z22func_with_indirect_arg1A(%class.A addrspace(5)* %[[r2]])
+// CHECK: call void @_ZN1AD1Ev(%class.A* %[[r0]])
+// CHECK: call void @_Z17func_with_ref_argR1A(%class.A* dereferenceable(4) addrspacecast (%class.A addrspace(1)* @g_a to %class.A*))
+void test_indirect_arg_global() {
+ func_with_indirect_arg(g_a);
+ func_with_ref_arg(g_a);
+}
+
+// CHECK-LABEL: define void @_Z19func_with_byval_arg1B(%class.B addrspace(5)* byval align 4 %b)
+// CHECK: %p = alloca %class.B*, align 8, addrspace(5)
+// CHECK: %[[r1:.+]] = addrspacecast %class.B* addrspace(5)* %p to %class.B**
+// CHECK: %[[r0:.+]] = addrspacecast %class.B addrspace(5)* %b to %class.B*
+// CHECK: store %class.B* %[[r0]], %class.B** %[[r1]], align 8
+void func_with_byval_arg(B b) {
+ B *p = &b;
+}
+
+// CHECK-LABEL: define void @_Z19test_byval_arg_autov()
+// CHECK: %b = alloca %class.B, align 4, addrspace(5)
+// CHECK: %[[r0:.+]] = addrspacecast %class.B addrspace(5)* %b to %class.B*
+// CHECK: %agg.tmp = alloca %class.B, align 4, addrspace(5)
+// CHECK: %[[r1:.+]] = addrspacecast %class.B addrspace(5)* %agg.tmp to %class.B*
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
+// CHECK: %[[r4:.+]] = addrspacecast %class.B* %[[r1]] to %class.B addrspace(5)*
+// CHECK: call void @_Z19func_with_byval_arg1B(%class.B addrspace(5)* byval align 4 %[[r4]])
+// CHECK: call void @_Z17func_with_ref_argR1B(%class.B* dereferenceable(400) %[[r0]])
+void test_byval_arg_auto() {
+ B b;
+ func_with_byval_arg(b);
+ func_with_ref_arg(b);
+}
+
+// CHECK-LABEL: define void @_Z21test_byval_arg_globalv()
+// CHECK: %agg.tmp = alloca %class.B, align 4, addrspace(5)
+// CHECK: %[[r0:.+]] = addrspacecast %class.B addrspace(5)* %agg.tmp to %class.B*
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
+// CHECK: %[[r2:.+]] = addrspacecast %class.B* %[[r0]] to %class.B addrspace(5)*
+// CHECK: call void @_Z19func_with_byval_arg1B(%class.B addrspace(5)* byval align 4 %[[r2]])
+// CHECK: call void @_Z17func_with_ref_argR1B(%class.B* dereferenceable(400) addrspacecast (%class.B addrspace(1)* @g_b to %class.B*))
+void test_byval_arg_global() {
+ func_with_byval_arg(g_b);
+ func_with_ref_arg(g_b);
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/amdgcn-string-literal.cpp b/src/llvm-project/clang/test/CodeGenCXX/amdgcn-string-literal.cpp
new file mode 100644
index 0000000..70be249
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/amdgcn-string-literal.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -emit-llvm %s -o - | FileCheck %s
+
+// CHECK: @.str = private unnamed_addr addrspace(4) constant [6 x i8] c"g_str\00", align 1
+// CHECK: @g_str = addrspace(1) global i8* addrspacecast (i8 addrspace(4)* getelementptr inbounds ([6 x i8], [6 x i8] addrspace(4)* @.str, i32 0, i32 0) to i8*), align 8
+// CHECK: @g_array = addrspace(1) global [8 x i8] c"g_array\00", align 1
+// CHECK: @.str.1 = private unnamed_addr addrspace(4) constant [6 x i8] c"l_str\00", align 1
+// CHECK: @__const._Z1fv.l_array = private unnamed_addr addrspace(4) constant [8 x i8] c"l_array\00", align 1
+
+const char* g_str = "g_str";
+char g_array[] = "g_array";
+
+void g(const char* p);
+
+// CHECK-LABEL: define void @_Z1fv()
+void f() {
+ const char* l_str = "l_str";
+
+ // CHECK: call void @llvm.memcpy.p0i8.p4i8.i64
+ char l_array[] = "l_array";
+
+ g(g_str);
+ g(g_array);
+ g(l_str);
+ g(l_array);
+
+ const char* p = g_str;
+ g(p);
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/amdgcn_declspec_get.cpp b/src/llvm-project/clang/test/CodeGenCXX/amdgcn_declspec_get.cpp
new file mode 100644
index 0000000..93f7a36
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/amdgcn_declspec_get.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -emit-llvm -O3 -fdeclspec \
+// RUN: -disable-llvm-passes -o - %s | FileCheck %s
+
+int get_x();
+
+struct A {
+ __declspec(property(get = _get_x)) int x;
+ static int _get_x(void) {
+ return get_x();
+ };
+};
+
+extern const A a;
+
+// CHECK-LABEL: define void @_Z4testv()
+// CHECK: %i = alloca i32, align 4, addrspace(5)
+// CHECK: %[[ii:.*]] = addrspacecast i32 addrspace(5)* %i to i32*
+// CHECK: %[[cast:.*]] = bitcast i32 addrspace(5)* %i to i8 addrspace(5)*
+// CHECK: call void @llvm.lifetime.start.p5i8(i64 4, i8 addrspace(5)* %[[cast]])
+// CHECK: %call = call i32 @_ZN1A6_get_xEv()
+// CHECK: store i32 %call, i32* %[[ii]]
+// CHECK: %[[cast2:.*]] = bitcast i32 addrspace(5)* %i to i8 addrspace(5)*
+// CHECK: call void @llvm.lifetime.end.p5i8(i64 4, i8 addrspace(5)* %[[cast2]])
+void test()
+{
+ int i = a.x;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/anonymous-namespaces.cpp b/src/llvm-project/clang/test/CodeGenCXX/anonymous-namespaces.cpp
new file mode 100644
index 0000000..b2857ff
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/anonymous-namespaces.cpp
@@ -0,0 +1,84 @@
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -triple x86_64-apple-darwin10 -emit-llvm %s -o - > %t
+// RUN: FileCheck %s -check-prefix=CHECK-1 < %t
+// RUN: FileCheck %s -check-prefix=CHECK-2 < %t
+
+int f();
+
+namespace {
+ // CHECK-1: @_ZN12_GLOBAL__N_11bE = internal global i32 0
+ // CHECK-1: @_ZN12_GLOBAL__N_11cE = internal global i32 0
+ // CHECK-1: @_ZN12_GLOBAL__N_12c2E = internal global i32 0
+ // CHECK-1: @_ZN12_GLOBAL__N_11D1dE = internal global i32 0
+ // CHECK-1: @_ZN12_GLOBAL__N_11aE = internal global i32 0
+ int a = 0;
+
+ int b = f();
+
+ static int c = f();
+
+ // Note, we can't use an 'L' mangling for c or c2 (like GCC does) based on
+ // the 'static' specifier, because the variable can be redeclared without it.
+ extern int c2;
+ int g() { return c2; }
+ static int c2 = f();
+
+ class D {
+ static int d;
+ };
+
+ int D::d = f();
+
+ // Check for generation of a VTT with internal linkage
+ // CHECK-1: @_ZTSN12_GLOBAL__N_11X1EE = internal constant
+ struct X {
+ struct EBase { };
+ struct E : public virtual EBase { virtual ~E() {} };
+ };
+
+ // CHECK-1-LABEL: define internal i32 @_ZN12_GLOBAL__N_13fooEv()
+ int foo() {
+ return 32;
+ }
+
+ // CHECK-1-LABEL: define internal i32 @_ZN12_GLOBAL__N_11A3fooEv()
+ namespace A {
+ int foo() {
+ return 45;
+ }
+ }
+}
+
+int concrete() {
+ return a + foo() + A::foo();
+}
+
+void test_XE() { throw X::E(); }
+
+// Miscompile on llvmc plugins.
+namespace test2 {
+ struct A {
+ template <class T> struct B {
+ static void foo() {}
+ };
+ };
+ namespace {
+ struct C;
+ }
+
+ // CHECK-2-LABEL: define void @_ZN5test24testEv()
+ // CHECK-2: call void @_ZN5test21A1BINS_12_GLOBAL__N_11CEE3fooEv()
+ void test() {
+ A::B<C>::foo();
+ }
+
+ // CHECK-2-LABEL: define internal void @_ZN5test21A1BINS_12_GLOBAL__N_11CEE3fooEv()
+}
+
+namespace {
+
+int bar() {
+ extern int a;
+ return a;
+}
+
+} // namespace
diff --git a/src/llvm-project/clang/test/CodeGenCXX/anonymous-union-member-initializer.cpp b/src/llvm-project/clang/test/CodeGenCXX/anonymous-union-member-initializer.cpp
new file mode 100644
index 0000000..e8c4480
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/anonymous-union-member-initializer.cpp
@@ -0,0 +1,191 @@
+// 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 {
+ int a;
+ void* b;
+ };
+
+ A() : a(0) { }
+};
+
+A a;
+
+namespace PR7021 {
+ struct X
+ {
+ union { long l; };
+ };
+
+ // CHECK-LABEL: define void @_ZN6PR70211fENS_1XES0_
+ void f(X x, X z) {
+ X x1;
+
+ // CHECK: store i64 1, i64
+ x1.l = 1;
+
+ // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
+ X x2(x1);
+
+ X x3;
+ // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
+ x3 = x1;
+
+ // CHECK: ret void
+ }
+}
+
+namespace test2 {
+ struct A {
+ struct {
+ union {
+ int b;
+ };
+ };
+
+ A();
+ };
+
+ A::A() : b(10) { }
+ // CHECK-LABEL: define void @_ZN5test21AC2Ev(
+ // CHECK-NOT: }
+ // CHECK: store i32 10
+ // CHECK: }
+}
+
+namespace PR10512 {
+ struct A {
+ A();
+ A(int);
+ A(long);
+
+ struct {
+ struct {int x;};
+ struct {int y;};
+ };
+ };
+
+ // CHECK-LABEL: define void @_ZN7PR105121AC2Ev
+ // CHECK: [[THISADDR:%[a-zA-Z0-9.]+]] = alloca [[A:%"struct[A-Za-z0-9:.]+"]]
+ // CHECK-NEXT: store [[A]]* [[THIS:%[a-zA-Z0-9.]+]], [[A]]** [[THISADDR]]
+ // CHECK-NEXT: [[THIS1:%[a-zA-Z0-9.]+]] = load [[A]]*, [[A]]** [[THISADDR]]
+ // CHECK-NEXT: ret void
+ A::A() {}
+
+ // CHECK-LABEL: define void @_ZN7PR105121AC2Ei
+ // CHECK: [[THISADDR:%[a-zA-Z0-9.]+]] = alloca [[A:%"struct[A-Za-z0-9:.]+"]]
+ // CHECK-NEXT: [[XADDR:%[a-zA-Z0-9.]+]] = alloca i32
+ // CHECK-NEXT: store [[A]]* [[THIS:%[a-zA-Z0-9.]+]], [[A]]** [[THISADDR]]
+ // CHECK-NEXT: store i32 [[X:%[a-zA-Z0-9.]+]], i32* [[XADDR]]
+ // CHECK-NEXT: [[THIS1:%[a-zA-Z0-9.]+]] = load [[A]]*, [[A]]** [[THISADDR]]
+ // CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 0}}
+ // CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 0}}
+ // CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 0}}
+ // CHECK-NEXT: [[TMP:%[a-zA-Z0-9.]+]] = load i32, i32* [[XADDR]]
+ // CHECK-NEXT: store i32 [[TMP]]
+ // CHECK-NEXT: ret void
+ A::A(int x) : x(x) { }
+
+ // CHECK-LABEL: define void @_ZN7PR105121AC2El
+ // CHECK: [[THISADDR:%[a-zA-Z0-9.]+]] = alloca [[A:%"struct[A-Za-z0-9:.]+"]]
+ // CHECK-NEXT: [[XADDR:%[a-zA-Z0-9.]+]] = alloca i64
+ // CHECK-NEXT: store [[A]]* [[THIS:%[a-zA-Z0-9.]+]], [[A]]** [[THISADDR]]
+ // CHECK-NEXT: store i64 [[X:%[a-zA-Z0-9.]+]], i64* [[XADDR]]
+ // CHECK-NEXT: [[THIS1:%[a-zA-Z0-9.]+]] = load [[A]]*, [[A]]** [[THISADDR]]
+ // CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 0}}
+ // CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 1}}
+ // CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 0}}
+ // CHECK-NEXT: [[TMP:%[a-zA-Z0-9.]+]] = load i64, i64* [[XADDR]]
+ // CHECK-NEXT: [[CONV:%[a-zA-Z0-9.]+]] = trunc i64 [[TMP]] to i32
+ // CHECK-NEXT: store i32 [[CONV]]
+ // CHECK-NEXT: ret void
+ A::A(long y) : y(y) { }
+}
+
+namespace test3 {
+ struct A {
+ union {
+ mutable char fibers[100];
+ struct {
+ void (*callback)(void*);
+ void *callback_value;
+ };
+ };
+
+ A();
+ };
+
+ A::A() : callback(0), callback_value(0) {}
+ // CHECK-LABEL: define void @_ZN5test31AC2Ev(
+ // CHECK: [[THIS:%.*]] = load
+ // CHECK-NEXT: [[UNION:%.*]] = getelementptr inbounds {{.*}} [[THIS]], i32 0, i32 0
+ // CHECK-NEXT: [[STRUCT:%.*]] = bitcast {{.*}}* [[UNION]] to
+ // CHECK-NEXT: [[CALLBACK:%.*]] = getelementptr inbounds {{.*}} [[STRUCT]], i32 0, i32 0
+ // CHECK: store
+ // CHECK-NEXT: [[UNION:%.*]] = getelementptr inbounds {{.*}} [[THIS]], i32 0, i32 0
+ // CHECK-NEXT: [[STRUCT:%.*]] = bitcast {{.*}}* [[UNION]] to
+ // CHECK-NEXT: [[CVALUE:%.*]] = getelementptr inbounds {{.*}} [[STRUCT]], i32 0, i32 1
+ // CHECK-NEXT: store i8* null, i8** [[CVALUE]]
+}
+
+struct S {
+ // CHECK: store i32 42
+ // CHECK: store i32 55
+ S() : x(42), y(55) {}
+ union {
+ struct {
+ int x;
+ union { int y; };
+ };
+ };
+} s;
+
+
+//PR8760
+template <typename T> struct Foo {
+ Foo() : ptr(__nullptr) {}
+ union {
+ T *ptr;
+ };
+};
+Foo<int> f;
+
+namespace PR9683 {
+ struct QueueEntry {
+ union {
+ struct {
+ void* mPtr;
+ union {
+ unsigned mSubmissionTag;
+ };
+ };
+ unsigned mValue;
+ };
+ QueueEntry() {}
+ };
+ QueueEntry QE;
+}
+
+namespace PR13154 {
+ struct IndirectReferenceField {
+ struct {
+ float &x;
+ };
+ IndirectReferenceField(float &x);
+ };
+ IndirectReferenceField::IndirectReferenceField(float &xx) : x(xx) {}
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/apple-kext-guard-variable.cpp b/src/llvm-project/clang/test/CodeGenCXX/apple-kext-guard-variable.cpp
new file mode 100644
index 0000000..ea4c148
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/apple-kext-guard-variable.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang -target x86_64-apple-darwin10 -S -o %t.s -Wno-stdlibcxx-not-found -mkernel -Xclang -verify %s
+
+// rdar://problem/9143356
+
+int foo();
+void test() {
+ static int y = 0;
+ static int x = foo(); // expected-error {{this initialization requires a guard variable, which the kernel does not support}}
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/apple-kext-indirect-call-2.cpp b/src/llvm-project/clang/test/CodeGenCXX/apple-kext-indirect-call-2.cpp
new file mode 100644
index 0000000..3b2cda8
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/apple-kext-indirect-call-2.cpp
@@ -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*] } { [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*] } { [4 x i8*] [i8* null, i8* null, i8* bitcast (i8* (%struct.Base*)* @_ZNK4Base3abcEv to i8*), i8* null] }
+// CHECK: @_ZTV8Derived2 = unnamed_addr constant { [5 x i8*] } { [5 x i8*] [i8* null, i8* null, i8* null, i8* bitcast (i8* (%struct.Derived2*)* @_ZNK8Derived23efgEv to i8*), i8* null] }
+// CHECK: @_ZTV2D2 = unnamed_addr constant { [5 x i8*] } { [5 x i8*] [i8* null, i8* null, i8* null, i8* bitcast (i8* (%struct.D2*)* @_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*)*, i8* (%struct.A*)** getelementptr inbounds (i8* (%struct.A*)*, 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.Base*)*, i8* (%struct.Base*)** getelementptr inbounds (i8* (%struct.Base*)*, i8* (%struct.Base*)** bitcast ({ [4 x i8*] }* @_ZTV4Base to i8* (%struct.Base*)**), 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.Derived2*)*, i8* (%struct.Derived2*)** getelementptr inbounds (i8* (%struct.Derived2*)*, i8* (%struct.Derived2*)** bitcast ({ [5 x i8*] }* @_ZTV8Derived2 to i8* (%struct.Derived2*)**), 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.D2*)*, i8* (%struct.D2*)** getelementptr inbounds (i8* (%struct.D2*)*, i8* (%struct.D2*)** bitcast ({ [5 x i8*] }* @_ZTV2D2 to i8* (%struct.D2*)**), i64 3)
+// CHECK-NEXT: [[W2:%.*]] = call i8* [[W1]]
+ char* c = p->D2::abc();
+}
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/apple-kext-indirect-call.cpp b/src/llvm-project/clang/test/CodeGenCXX/apple-kext-indirect-call.cpp
new file mode 100644
index 0000000..ac0e3f4
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/apple-kext-indirect-call.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fapple-kext -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: @_ZTV5TemplIiE = internal unnamed_addr constant { [5 x i8*] } { [5 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTI5TemplIiE to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiE1fEv to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiE1gEv to i8*), i8* null] }
+
+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*)*, void (%struct.Base*)** bitcast ({ [4 x i8*] }* @_ZTV4Base to void (%struct.Base*)**), i64 2)
+// CHECK-NOT: call void @_ZNK4Base3abcEv
+
+template<class T>
+struct Templ {
+ virtual void f() {}
+ virtual void g() {}
+};
+template<class T>
+struct SubTempl : public Templ<T> {
+ virtual void f() {} // override
+ virtual void g() {} // override
+};
+
+void f(SubTempl<int>* t) {
+ // Qualified calls go through the (qualified) vtable in apple-kext mode.
+ // Since t's this pointer points to SubTempl's vtable, the call needs
+ // to load Templ<int>'s vtable. Hence, Templ<int>::g needs to be
+ // instantiated in this TU, for it's referenced by the vtable.
+ // (This happens only in apple-kext mode; elsewhere virtual calls can always
+ // use the vtable pointer off this instead of having to load the vtable
+ // symbol.)
+ t->Templ::f();
+}
+
+// CHECK: getelementptr inbounds (void (%struct.Templ*)*, void (%struct.Templ*)** bitcast ({ [5 x i8*] }* @_ZTV5TemplIiE to void (%struct.Templ*)**), i64 2)
+// CHECK: define internal void @_ZN5TemplIiE1fEv(%struct.Templ* %this)
+// CHECK: define internal void @_ZN5TemplIiE1gEv(%struct.Templ* %this)
diff --git a/src/llvm-project/clang/test/CodeGenCXX/apple-kext-indirect-virtual-dtor-call.cpp b/src/llvm-project/clang/test/CodeGenCXX/apple-kext-indirect-virtual-dtor-call.cpp
new file mode 100644
index 0000000..3f26cb4
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/apple-kext-indirect-virtual-dtor-call.cpp
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fapple-kext -fno-rtti -disable-O0-optnone -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: @_ZTV5TemplIiE = internal unnamed_addr constant { [7 x i8*] } { [7 x i8*] [i8* null, i8* null, i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiED1Ev to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiED0Ev to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiE1fEv to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiE1gEv to i8*), i8* null] }
+
+struct B1 {
+ virtual ~B1();
+};
+
+B1::~B1() {}
+
+void DELETE(B1 *pb1) {
+ pb1->B1::~B1();
+}
+// CHECK-LABEL: define void @_ZN2B1D0Ev
+// CHECK: [[T1:%.*]] = load void (%struct.B1*)*, void (%struct.B1*)** getelementptr inbounds (void (%struct.B1*)*, void (%struct.B1*)** bitcast ({ [5 x i8*] }* @_ZTV2B1 to void (%struct.B1*)**), i64 2)
+// CHECK-NEXT: call void [[T1]](%struct.B1* [[T2:%.*]])
+// CHECK-LABEL: define void @_Z6DELETEP2B1
+// CHECK: [[T3:%.*]] = load void (%struct.B1*)*, void (%struct.B1*)** getelementptr inbounds (void (%struct.B1*)*, void (%struct.B1*)** bitcast ({ [5 x i8*] }* @_ZTV2B1 to void (%struct.B1*)**), i64 2)
+// CHECK-NEXT: call void [[T3]](%struct.B1* [[T4:%.*]])
+
+template<class T>
+struct Templ {
+ virtual ~Templ(); // Out-of-line so that the destructor doesn't cause a vtable
+ virtual void f() {}
+ virtual void g() {}
+};
+template<class T>
+struct SubTempl : public Templ<T> {
+ virtual ~SubTempl() {} // override
+ virtual void f() {} // override
+ virtual void g() {} // override
+};
+
+void f(SubTempl<int>* t) {
+ // Qualified calls go through the (qualified) vtable in apple-kext mode.
+ // Since t's this pointer points to SubTempl's vtable, the call needs
+ // to load Templ<int>'s vtable. Hence, Templ<int>::g needs to be
+ // instantiated in this TU, for it's referenced by the vtable.
+ // (This happens only in apple-kext mode; elsewhere virtual calls can always
+ // use the vtable pointer off this instead of having to load the vtable
+ // symbol.)
+ t->Templ::~Templ();
+}
+
+// CHECK: getelementptr inbounds (void (%struct.Templ*)*, void (%struct.Templ*)** bitcast ({ [7 x i8*] }* @_ZTV5TemplIiE to void (%struct.Templ*)**), i64 2)
+// CHECK: declare void @_ZN5TemplIiED0Ev(%struct.Templ*)
+// CHECK: define internal void @_ZN5TemplIiE1fEv(%struct.Templ* %this)
+// CHECK: define internal void @_ZN5TemplIiE1gEv(%struct.Templ* %this)
diff --git a/src/llvm-project/clang/test/CodeGenCXX/apple-kext-linkage.cpp b/src/llvm-project/clang/test/CodeGenCXX/apple-kext-linkage.cpp
new file mode 100644
index 0000000..e66b038
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/apple-kext-linkage.cpp
@@ -0,0 +1,33 @@
+// 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
+}
+
+// CHECK-LABEL: define internal i32 @_Z1fj(
+inline unsigned f(unsigned n) { return n == 0 ? 0 : n + f(n-1); }
+
+unsigned g(unsigned n) { return f(n); }
+
+// rdar://problem/10133200: give explicit instantiations external linkage in kernel mode
+// CHECK-LABEL: define void @_Z3barIiEvv()
+template <typename T> void bar() {}
+template void bar<int>();
+
+// CHECK-LABEL: define internal i32 @_Z5identIiET_S0_(
+template <typename X> X ident(X x) { return x; }
+
+int foo(int n) { return ident(n); }
+
+// CHECK-LABEL: define internal void @_ZN7DerivedD1Ev(
+// CHECK-LABEL: define internal void @_ZN7DerivedD0Ev(
+// CHECK-LABEL: define internal void @_ZN7DeriveddlEPv(
diff --git a/src/llvm-project/clang/test/CodeGenCXX/apple-kext-no-staticinit-section.cpp b/src/llvm-project/clang/test/CodeGenCXX/apple-kext-no-staticinit-section.cpp
new file mode 100644
index 0000000..5d258f6
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/apple-kext-no-staticinit-section.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fapple-kext -fno-rtti -disable-O0-optnone -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/src/llvm-project/clang/test/CodeGenCXX/apple-kext.cpp b/src/llvm-project/clang/test/CodeGenCXX/apple-kext.cpp
new file mode 100644
index 0000000..0d7ccfb
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/apple-kext.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fno-use-cxa-atexit -fapple-kext -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: @_ZN5test01aE = global [[A:%.*]] zeroinitializer
+// CHECK: @llvm.global_ctors = appending global {{.*}} { i32 65535, void ()* [[CTOR0:@.*]], i8* null }
+// CHECK: @llvm.global_dtors = appending global {{.*}} { i32 65535, void ()* [[DTOR0:@.*]], i8* null }
+
+// rdar://11241230
+namespace test0 {
+ struct A { A(); ~A(); };
+ A a;
+}
+// CHECK: define internal void [[CTOR0_:@.*]]()
+// CHECK: call void @_ZN5test01AC1Ev([[A]]* @_ZN5test01aE)
+// CHECK-NEXT: ret void
+
+// CHECK: define internal void [[CTOR0]]()
+// CHECK: call void [[CTOR0_]]()
+// CHECK-NEXT: ret void
+
+// CHECK: define internal void [[DTOR0]]()
+// CHECK: call void @_ZN5test01AD1Ev([[A]]* @_ZN5test01aE)
+// CHECK-NEXT: ret void
diff --git a/src/llvm-project/clang/test/CodeGenCXX/arm-cc.cpp b/src/llvm-project/clang/test/CodeGenCXX/arm-cc.cpp
new file mode 100644
index 0000000..6027746
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/arm-cc.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 %s -triple=arm-unknown-linux-gnueabi -target-abi aapcs -emit-llvm -o - | FileCheck %s
+
+class SMLoc {
+ const char *Ptr;
+public:
+ SMLoc();
+ SMLoc(const SMLoc &RHS);
+};
+SMLoc foo(void *p);
+void bar(void *x) {
+ foo(x);
+}
+void zed(SMLoc x);
+void baz() {
+ SMLoc a;
+ zed(a);
+}
+
+// CHECK: declare void @_Z3fooPv(%class.SMLoc* sret, i8*)
+// CHECK: declare void @_Z3zed5SMLoc(%class.SMLoc*)
diff --git a/src/llvm-project/clang/test/CodeGenCXX/arm-swiftcall.cpp b/src/llvm-project/clang/test/CodeGenCXX/arm-swiftcall.cpp
new file mode 100644
index 0000000..36a5afa
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/arm-swiftcall.cpp
@@ -0,0 +1,125 @@
+// RUN: %clang_cc1 -triple armv7-apple-darwin9 -emit-llvm -o - %s -Wno-return-type-c-linkage -std=c++03 | FileCheck %s -check-prefixes=CHECK
+
+// This isn't really testing anything ARM-specific; it's just a convenient
+// 32-bit platform.
+
+#define SWIFTCALL __attribute__((swiftcall))
+#define OUT __attribute__((swift_indirect_result))
+#define ERROR __attribute__((swift_error_result))
+#define CONTEXT __attribute__((swift_context))
+
+/*****************************************************************************/
+/********************************** LOWERING *********************************/
+/*****************************************************************************/
+
+#define TEST(TYPE) \
+ extern "C" SWIFTCALL TYPE return_##TYPE(void) { \
+ TYPE result = {}; \
+ return result; \
+ } \
+ extern "C" SWIFTCALL void take_##TYPE(TYPE v) { \
+ } \
+ extern "C" void test_##TYPE() { \
+ take_##TYPE(return_##TYPE()); \
+ }
+
+/*****************************************************************************/
+/*********************************** STRUCTS *********************************/
+/*****************************************************************************/
+
+typedef struct {
+} struct_empty;
+TEST(struct_empty);
+// CHECK-LABEL: define {{.*}} @return_struct_empty()
+// CHECK: ret void
+// CHECK-LABEL: define {{.*}} @take_struct_empty()
+// CHECK: ret void
+
+// This is only properly testable in C++ because it relies on empty structs
+// actually taking up space in a structure without requiring any extra data
+// to be passed.
+typedef struct {
+ int x;
+ struct_empty padding[2];
+ char c1;
+ float f0;
+ float f1;
+} struct_1;
+TEST(struct_1);
+// CHECK-LABEL: define {{.*}} @return_struct_1()
+// CHECK: [[RET:%.*]] = alloca [[REC:%.*]], align 4
+// CHECK: @llvm.memset
+// CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[RET]] to [[AGG:{ i32, \[2 x i8\], i8, \[1 x i8\], float, float }]]*
+// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
+// CHECK: [[FIRST:%.*]] = load i32, i32* [[T0]], align 4
+// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 2
+// CHECK: [[SECOND:%.*]] = load i8, i8* [[T0]], align 2
+// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 4
+// CHECK: [[THIRD:%.*]] = load float, float* [[T0]], align 4
+// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 5
+// CHECK: [[FOURTH:%.*]] = load float, float* [[T0]], align 4
+// CHECK: [[T0:%.*]] = insertvalue [[UAGG:{ i32, i8, float, float }]] undef, i32 [[FIRST]], 0
+// CHECK: [[T1:%.*]] = insertvalue [[UAGG]] [[T0]], i8 [[SECOND]], 1
+// CHECK: [[T2:%.*]] = insertvalue [[UAGG]] [[T1]], float [[THIRD]], 2
+// CHECK: [[T3:%.*]] = insertvalue [[UAGG]] [[T2]], float [[FOURTH]], 3
+// CHECK: ret [[UAGG]] [[T3]]
+// CHECK-LABEL: define {{.*}} @take_struct_1(i32, i8, float, float)
+// CHECK: [[V:%.*]] = alloca [[REC]], align 4
+// CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[V]] to [[AGG]]*
+// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
+// CHECK: store i32 %0, i32* [[T0]], align 4
+// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 2
+// CHECK: store i8 %1, i8* [[T0]], align 2
+// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 4
+// CHECK: store float %2, float* [[T0]], align 4
+// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 5
+// CHECK: store float %3, float* [[T0]], align 4
+// CHECK: ret void
+// CHECK-LABEL: define void @test_struct_1()
+// CHECK: [[TMP:%.*]] = alloca [[REC]], align 4
+// CHECK: [[CALL:%.*]] = call [[SWIFTCC:swiftcc]] [[UAGG]] @return_struct_1()
+// CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP]] to [[AGG]]*
+// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
+// CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 0
+// CHECK: store i32 [[T1]], i32* [[T0]], align 4
+// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 2
+// CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 1
+// CHECK: store i8 [[T1]], i8* [[T0]], align 2
+// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 4
+// CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 2
+// CHECK: store float [[T1]], float* [[T0]], align 4
+// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 5
+// CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 3
+// CHECK: store float [[T1]], float* [[T0]], align 4
+// CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP]] to [[AGG]]*
+// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0
+// CHECK: [[FIRST:%.*]] = load i32, i32* [[T0]], align 4
+// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 2
+// CHECK: [[SECOND:%.*]] = load i8, i8* [[T0]], align 2
+// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 4
+// CHECK: [[THIRD:%.*]] = load float, float* [[T0]], align 4
+// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 5
+// CHECK: [[FOURTH:%.*]] = load float, float* [[T0]], align 4
+// CHECK: call [[SWIFTCC]] void @take_struct_1(i32 [[FIRST]], i8 [[SECOND]], float [[THIRD]], float [[FOURTH]])
+// CHECK: ret void
+
+struct struct_indirect_1 {
+ int x;
+ ~struct_indirect_1();
+};
+TEST(struct_indirect_1)
+
+// CHECK-LABEL: define {{.*}} void @return_struct_indirect_1({{.*}} noalias sret
+
+// Should not be byval.
+// CHECK-LABEL: define {{.*}} void @take_struct_indirect_1({{.*}}*{{( %.*)?}})
+
+// Do a simple standalone test here of a function definition to ensure that
+// we don't have problems due to failure to eagerly synthesize a copy
+// constructor declaration.
+class struct_trivial {
+ int x;
+};
+// CHECK-LABEL define void @test_struct_trivial(i32{{( %.*)?}})
+extern "C" SWIFTCALL
+void test_struct_trivial(struct_trivial triv) {}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/arm-vaarg.cpp b/src/llvm-project/clang/test/CodeGenCXX/arm-vaarg.cpp
new file mode 100644
index 0000000..0220ac8
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/arm-vaarg.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -triple armv7-apple-ios -emit-llvm -o - %s | FileCheck %s
+struct Empty {};
+
+Empty emptyvar;
+
+int take_args(int a, ...) {
+ __builtin_va_list l;
+ __builtin_va_start(l, a);
+// CHECK: call void @llvm.va_start
+
+ emptyvar = __builtin_va_arg(l, Empty);
+// CHECK: load i8*, i8**
+// CHECK-NOT: getelementptr
+// CHECK: [[EMPTY_PTR:%[a-zA-Z0-9._]+]] = bitcast i8* {{%[a-zA-Z0-9._]+}} to %struct.Empty*
+
+ // It's conceivable that EMPTY_PTR may not actually be a valid pointer
+ // (e.g. it's at the very bottom of the stack and the next page is
+ // invalid). This doesn't matter provided it's never loaded (there's no
+ // well-defined way to tell), but it becomes a problem if we do try to use it.
+// CHECK-NOT: load %struct.Empty, %struct.Empty* [[EMPTY_PTR]]
+
+ int i = __builtin_va_arg(l, int);
+// CHECK: load i32, i32*
+
+ __builtin_va_end(l);
+ return i;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/arm.cpp b/src/llvm-project/clang/test/CodeGenCXX/arm.cpp
new file mode 100644
index 0000000..7eba017
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/arm.cpp
@@ -0,0 +1,422 @@
+// RUN: %clang_cc1 %s -triple=thumbv7-apple-ios6.0 -fno-use-cxa-atexit -target-abi apcs-gnu -emit-llvm -std=gnu++98 -o - -fexceptions | FileCheck -check-prefix=CHECK -check-prefix=CHECK98 %s
+// RUN: %clang_cc1 %s -triple=thumbv7-apple-ios6.0 -fno-use-cxa-atexit -target-abi apcs-gnu -emit-llvm -std=gnu++11 -o - -fexceptions | FileCheck -check-prefix=CHECK -check-prefix=CHECK11 %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 {
+public:
+ foo();
+ virtual ~foo();
+};
+
+class bar : public foo {
+public:
+ bar();
+};
+
+// The global dtor needs the right calling conv with -fno-use-cxa-atexit
+// rdar://7817590
+bar baz;
+
+// PR9593
+// Make sure atexit(3) is used for global dtors.
+
+// CHECK: call [[BAR:%.*]]* @_ZN3barC1Ev(
+// CHECK-NEXT: call i32 @atexit(void ()* @__dtor_baz)
+
+// CHECK-NOT: @_GLOBAL__D_a()
+// CHECK-LABEL: define internal void @__dtor_baz()
+// CHECK: call [[BAR]]* @_ZN3barD1Ev([[BAR]]* @baz)
+
+// Destructors and constructors must return this.
+namespace test1 {
+ void foo();
+
+ struct A {
+ A(int i) { foo(); }
+ ~A() { foo(); }
+ void bar() { foo(); }
+ };
+
+ // CHECK-LABEL: define void @_ZN5test14testEv()
+ void test() {
+ // CHECK: [[AV:%.*]] = alloca [[A:%.*]], align 1
+ // CHECK: call [[A]]* @_ZN5test11AC1Ei([[A]]* [[AV]], i32 10)
+ // CHECK: invoke void @_ZN5test11A3barEv([[A]]* [[AV]])
+ // CHECK: call [[A]]* @_ZN5test11AD1Ev([[A]]* [[AV]])
+ // CHECK: ret void
+ A a = 10;
+ a.bar();
+ }
+
+ // CHECK: define linkonce_odr [[A]]* @_ZN5test11AC1Ei([[A]]* returned %this, i32 %i) unnamed_addr
+ // CHECK: [[THIS:%.*]] = alloca [[A]]*, align 4
+ // CHECK: store [[A]]* {{.*}}, [[A]]** [[THIS]]
+ // CHECK: [[THIS1:%.*]] = load [[A]]*, [[A]]** [[THIS]]
+ // CHECK: {{%.*}} = call [[A]]* @_ZN5test11AC2Ei(
+ // CHECK: ret [[A]]* [[THIS1]]
+
+ // CHECK: define linkonce_odr [[A]]* @_ZN5test11AD1Ev([[A]]* returned %this) unnamed_addr
+ // CHECK: [[THIS:%.*]] = alloca [[A]]*, align 4
+ // CHECK: store [[A]]* {{.*}}, [[A]]** [[THIS]]
+ // CHECK: [[THIS1:%.*]] = load [[A]]*, [[A]]** [[THIS]]
+ // CHECK: {{%.*}} = call [[A]]* @_ZN5test11AD2Ev(
+ // CHECK: ret [[A]]* [[THIS1]]
+}
+
+// Awkward virtual cases.
+namespace test2 {
+ void foo();
+
+ struct A {
+ int x;
+
+ A(int);
+ virtual ~A() { foo(); }
+ };
+
+ struct B {
+ int y;
+ int z;
+
+ B(int);
+ virtual ~B() { foo(); }
+ };
+
+ struct C : A, virtual B {
+ int q;
+
+ C(int i) : A(i), B(i) { foo(); }
+ ~C() { foo(); }
+ };
+
+ void test() {
+ C c = 10;
+ }
+
+ // Tests at eof
+}
+
+namespace test3 {
+ struct A {
+ int x;
+ ~A();
+ };
+
+ void a() {
+ // CHECK-LABEL: define void @_ZN5test31aEv()
+ // CHECK: call i8* @_Znam(i32 48)
+ // CHECK: store i32 4
+ // CHECK: store i32 10
+ A *x = new A[10];
+ }
+
+ void b(int n) {
+ // CHECK-LABEL: define void @_ZN5test31bEi(
+ // CHECK: [[N:%.*]] = load i32, i32*
+ // CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 4)
+ // CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8)
+ // CHECK: [[OR:%.*]] = or i1
+ // CHECK: [[SZ:%.*]] = select i1 [[OR]]
+ // CHECK: call i8* @_Znam(i32 [[SZ]])
+ // CHECK: store i32 4
+ // CHECK: store i32 [[N]]
+ A *x = new A[n];
+ }
+
+ void c() {
+ // CHECK-LABEL: define void @_ZN5test31cEv()
+ // CHECK: call i8* @_Znam(i32 808)
+ // CHECK: store i32 4
+ // CHECK: store i32 200
+ A (*x)[20] = new A[10][20];
+ }
+
+ void d(int n) {
+ // CHECK-LABEL: define void @_ZN5test31dEi(
+ // CHECK: [[N:%.*]] = load i32, i32*
+ // CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 80)
+ // CHECK: [[NE:%.*]] = mul i32 [[N]], 20
+ // CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8)
+ // CHECK: [[SZ:%.*]] = select
+ // CHECK: call i8* @_Znam(i32 [[SZ]])
+ // CHECK: store i32 4
+ // CHECK: store i32 [[NE]]
+ A (*x)[20] = new A[n][20];
+ }
+
+ void e(A *x) {
+ // CHECK-LABEL: define void @_ZN5test31eEPNS_1AE(
+ // CHECK: icmp eq {{.*}}, null
+ // CHECK: getelementptr {{.*}}, i32 -8
+ // CHECK: getelementptr {{.*}}, i32 4
+ // CHECK: bitcast {{.*}} to i32*
+ // CHECK: load
+ // CHECK98: invoke {{.*}} @_ZN5test31AD1Ev
+ // CHECK11: call {{.*}} @_ZN5test31AD1Ev
+ // CHECK: call void @_ZdaPv
+ delete [] x;
+ }
+
+ void f(A (*x)[20]) {
+ // CHECK-LABEL: define void @_ZN5test31fEPA20_NS_1AE(
+ // CHECK: icmp eq {{.*}}, null
+ // CHECK: getelementptr {{.*}}, i32 -8
+ // CHECK: getelementptr {{.*}}, i32 4
+ // CHECK: bitcast {{.*}} to i32*
+ // CHECK: load
+ // CHECK98: invoke {{.*}} @_ZN5test31AD1Ev
+ // CHECK11: call {{.*}} @_ZN5test31AD1Ev
+ // CHECK: call void @_ZdaPv
+ delete [] x;
+ }
+}
+
+namespace test4 {
+ struct A {
+ int x;
+ void operator delete[](void *, size_t sz);
+ };
+
+ void a() {
+ // CHECK-LABEL: define void @_ZN5test41aEv()
+ // CHECK: call i8* @_Znam(i32 48)
+ // CHECK: store i32 4
+ // CHECK: store i32 10
+ A *x = new A[10];
+ }
+
+ void b(int n) {
+ // CHECK-LABEL: define void @_ZN5test41bEi(
+ // CHECK: [[N:%.*]] = load i32, i32*
+ // CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 4)
+ // CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8)
+ // CHECK: [[SZ:%.*]] = select
+ // CHECK: call i8* @_Znam(i32 [[SZ]])
+ // CHECK: store i32 4
+ // CHECK: store i32 [[N]]
+ A *x = new A[n];
+ }
+
+ void c() {
+ // CHECK-LABEL: define void @_ZN5test41cEv()
+ // CHECK: call i8* @_Znam(i32 808)
+ // CHECK: store i32 4
+ // CHECK: store i32 200
+ A (*x)[20] = new A[10][20];
+ }
+
+ void d(int n) {
+ // CHECK-LABEL: define void @_ZN5test41dEi(
+ // CHECK: [[N:%.*]] = load i32, i32*
+ // CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 80)
+ // CHECK: [[NE:%.*]] = mul i32 [[N]], 20
+ // CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8)
+ // CHECK: [[SZ:%.*]] = select
+ // CHECK: call i8* @_Znam(i32 [[SZ]])
+ // CHECK: store i32 4
+ // CHECK: store i32 [[NE]]
+ A (*x)[20] = new A[n][20];
+ }
+
+ void e(A *x) {
+ // CHECK-LABEL: define void @_ZN5test41eEPNS_1AE(
+ // CHECK: [[ALLOC:%.*]] = getelementptr inbounds {{.*}}, i32 -8
+ // CHECK: getelementptr inbounds {{.*}}, i32 4
+ // CHECK: bitcast
+ // CHECK: [[T0:%.*]] = load i32, i32*
+ // CHECK: [[T1:%.*]] = mul i32 4, [[T0]]
+ // CHECK: [[T2:%.*]] = add i32 [[T1]], 8
+ // CHECK: call void @_ZN5test41AdaEPvm(i8* [[ALLOC]], i32 [[T2]])
+ delete [] x;
+ }
+
+ void f(A (*x)[20]) {
+ // CHECK-LABEL: define void @_ZN5test41fEPA20_NS_1AE(
+ // CHECK: [[ALLOC:%.*]] = getelementptr inbounds {{.*}}, i32 -8
+ // CHECK: getelementptr inbounds {{.*}}, i32 4
+ // CHECK: bitcast
+ // CHECK: [[T0:%.*]] = load i32, i32*
+ // CHECK: [[T1:%.*]] = mul i32 4, [[T0]]
+ // CHECK: [[T2:%.*]] = add i32 [[T1]], 8
+ // CHECK: call void @_ZN5test41AdaEPvm(i8* [[ALLOC]], i32 [[T2]])
+ delete [] x;
+ }
+}
+
+// <rdar://problem/8386802>: don't crash
+namespace test5 {
+ struct A {
+ ~A();
+ };
+
+ // CHECK-LABEL: define void @_ZN5test54testEPNS_1AE
+ void test(A *a) {
+ // CHECK: [[PTR:%.*]] = alloca [[A:%.*]]*, align 4
+ // CHECK-NEXT: store [[A]]* {{.*}}, [[A]]** [[PTR]], align 4
+ // CHECK-NEXT: [[TMP:%.*]] = load [[A]]*, [[A]]** [[PTR]], align 4
+ // CHECK-NEXT: call [[A]]* @_ZN5test51AD1Ev([[A]]* [[TMP]])
+ // CHECK-NEXT: ret void
+ a->~A();
+ }
+}
+
+namespace test6 {
+ struct A {
+ virtual ~A();
+ };
+
+ // CHECK-LABEL: define void @_ZN5test64testEPNS_1AE
+ void test(A *a) {
+ // CHECK: [[AVAR:%.*]] = alloca [[A:%.*]]*, align 4
+ // CHECK-NEXT: store [[A]]* {{.*}}, [[A]]** [[AVAR]], align 4
+ // CHECK-NEXT: [[V:%.*]] = load [[A]]*, [[A]]** [[AVAR]], align 4
+ // CHECK-NEXT: [[ISNULL:%.*]] = icmp eq [[A]]* [[V]], null
+ // CHECK-NEXT: br i1 [[ISNULL]]
+ // CHECK: [[T0:%.*]] = bitcast [[A]]* [[V]] to void ([[A]]*)***
+ // CHECK-NEXT: [[T1:%.*]] = load void ([[A]]*)**, void ([[A]]*)*** [[T0]]
+ // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds void ([[A]]*)*, void ([[A]]*)** [[T1]], i64 1
+ // CHECK-NEXT: [[T3:%.*]] = load void ([[A]]*)*, void ([[A]]*)** [[T2]]
+ // CHECK-NEXT: call void [[T3]]([[A]]* [[V]])
+ // CHECK-NEXT: br label
+ // CHECK: ret void
+ delete a;
+ }
+}
+
+namespace test7 {
+ int foo();
+
+ // Static and guard tested at top of file
+
+ // CHECK-LABEL: define void @_ZN5test74testEv() {{.*}} personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ void test() {
+ // CHECK: [[T0:%.*]] = load atomic i8, i8* bitcast (i32* @_ZGVZN5test74testEvE1x to i8*) acquire, align 4
+ // CHECK-NEXT: [[T1:%.*]] = and i8 [[T0]], 1
+ // CHECK-NEXT: [[T2:%.*]] = icmp eq i8 [[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: landingpad { i8*, i32 }
+ // CHECK-NEXT: cleanup
+ // CHECK: call void @__cxa_guard_abort(i32* @_ZGVZN5test74testEvE1x)
+ // CHECK: resume { i8*, i32 }
+ }
+}
+
+namespace test8 {
+ struct A {
+ A();
+ ~A();
+ };
+
+ // Static and guard tested at top of file
+
+ // CHECK-LABEL: define void @_ZN5test84testEv() {{.*}} personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ void test() {
+ // CHECK: [[T0:%.*]] = load atomic i8, i8* bitcast (i32* @_ZGVZN5test84testEvE1x to i8*) acquire, align 4
+ // CHECK-NEXT: [[T1:%.*]] = and i8 [[T0]], 1
+ // CHECK-NEXT: [[T2:%.*]] = icmp eq i8 [[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: landingpad { i8*, i32 }
+ // CHECK-NEXT: cleanup
+ // CHECK: call void @__cxa_guard_abort(i32* @_ZGVZN5test84testEvE1x)
+ // CHECK: resume { i8*, i32 }
+ }
+}
+
+// rdar://12836470
+// Use a larger-than-mandated array cookie when allocating an
+// array whose type is overaligned.
+namespace test9 {
+ class __attribute__((aligned(16))) A {
+ float data[4];
+ public:
+ A();
+ ~A();
+ };
+
+ A *testNew(unsigned n) {
+ return new A[n];
+ }
+// CHECK: define [[TEST9:%.*]]* @_ZN5test97testNewEj(i32
+// CHECK: [[N_VAR:%.*]] = alloca i32, align 4
+// CHECK: [[N:%.*]] = load i32, i32* [[N_VAR]], align 4
+// CHECK-NEXT: [[T0:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[N]], i32 16)
+// CHECK-NEXT: [[O0:%.*]] = extractvalue { i32, i1 } [[T0]], 1
+// CHECK-NEXT: [[T1:%.*]] = extractvalue { i32, i1 } [[T0]], 0
+// CHECK-NEXT: [[T2:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[T1]], i32 16)
+// CHECK-NEXT: [[O1:%.*]] = extractvalue { i32, i1 } [[T2]], 1
+// CHECK-NEXT: [[OVERFLOW:%.*]] = or i1 [[O0]], [[O1]]
+// CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 0
+// CHECK-NEXT: [[T4:%.*]] = select i1 [[OVERFLOW]], i32 -1, i32 [[T3]]
+// CHECK-NEXT: [[ALLOC:%.*]] = call i8* @_Znam(i32 [[T4]])
+// CHECK-NEXT: [[T0:%.*]] = bitcast i8* [[ALLOC]] to i32*
+// CHECK-NEXT: store i32 16, i32* [[T0]]
+// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i32, i32* [[T0]], i32 1
+// CHECK-NEXT: store i32 [[N]], i32* [[T1]]
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds i8, i8* [[ALLOC]], i32 16
+// CHECK-NEXT: bitcast i8* [[T0]] to [[TEST9]]*
+// Array allocation follows.
+
+ void testDelete(A *array) {
+ delete[] array;
+ }
+// CHECK-LABEL: define void @_ZN5test910testDeleteEPNS_1AE(
+// CHECK: [[BEGIN:%.*]] = load [[TEST9]]*, [[TEST9]]**
+// CHECK-NEXT: [[T0:%.*]] = icmp eq [[TEST9]]* [[BEGIN]], null
+// CHECK-NEXT: br i1 [[T0]],
+// CHECK: [[T0:%.*]] = bitcast [[TEST9]]* [[BEGIN]] to i8*
+// CHECK-NEXT: [[ALLOC:%.*]] = getelementptr inbounds i8, i8* [[T0]], i32 -16
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds i8, i8* [[ALLOC]], i32 4
+// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to i32*
+// CHECK-NEXT: [[N:%.*]] = load i32, i32* [[T1]]
+// CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[TEST9]], [[TEST9]]* [[BEGIN]], i32 [[N]]
+// CHECK-NEXT: [[T0:%.*]] = icmp eq [[TEST9]]* [[BEGIN]], [[END]]
+// CHECK-NEXT: br i1 [[T0]],
+// Array deallocation follows.
+}
+
+ // CHECK: define linkonce_odr [[C:%.*]]* @_ZTv0_n12_N5test21CD1Ev(
+ // CHECK: call [[C]]* @_ZN5test21CD1Ev(
+ // CHECK: ret [[C]]* undef
+
+ // CHECK-LABEL: define linkonce_odr void @_ZTv0_n12_N5test21CD0Ev(
+ // CHECK: call void @_ZN5test21CD0Ev(
+ // CHECK: ret void
diff --git a/src/llvm-project/clang/test/CodeGenCXX/arm64-constructor-return.cpp b/src/llvm-project/clang/test/CodeGenCXX/arm64-constructor-return.cpp
new file mode 100644
index 0000000..cbe66ab
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/arm64-constructor-return.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 %s -triple=arm64-apple-ios7.0.0 -emit-llvm -o - | FileCheck %s
+// rdar://12162905
+
+struct S {
+ S();
+ int iField;
+};
+
+S::S() {
+ iField = 1;
+};
+
+// CHECK: %struct.S* @_ZN1SC2Ev(%struct.S* returned %this)
+
+// CHECK: %struct.S* @_ZN1SC1Ev(%struct.S* returned %this)
+// CHECK: [[THISADDR:%[a-zA-Z0-9.]+]] = alloca %struct.S*
+// CHECK: store %struct.S* %this, %struct.S** [[THISADDR]]
+// CHECK: [[THIS1:%.*]] = load %struct.S*, %struct.S** [[THISADDR]]
+// CHECK: ret %struct.S* [[THIS1]]
diff --git a/src/llvm-project/clang/test/CodeGenCXX/arm64-darwinpcs.cpp b/src/llvm-project/clang/test/CodeGenCXX/arm64-darwinpcs.cpp
new file mode 100644
index 0000000..0a0ec3a
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/arm64-darwinpcs.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -triple arm64-linux-gnu -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-linux-gnu -emit-llvm -o - %s -target-abi darwinpcs | FileCheck %s --check-prefix=CHECK-DARWIN
+
+void test_extensions(bool a, char b, short c) {}
+// CHECK: define void @_Z15test_extensionsbcs(i1 %a, i8 %b, i16 %c)
+// CHECK-DARWIN: define void @_Z15test_extensionsbcs(i1 zeroext %a, i8 signext %b, i16 signext %c)
+
+struct Empty {};
+void test_empty(Empty e) {}
+// CHECK: define void @_Z10test_empty5Empty(i8
+// CHECK-DARWIN: define void @_Z10test_empty5Empty()
+
+struct HFA {
+ float a[3];
+};
diff --git a/src/llvm-project/clang/test/CodeGenCXX/arm64-empty-struct.cpp b/src/llvm-project/clang/test/CodeGenCXX/arm64-empty-struct.cpp
new file mode 100644
index 0000000..6053c4a
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/arm64-empty-struct.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -triple arm64-apple-ios -target-abi darwinpcs -emit-llvm -o - %s | FileCheck %s
+struct Empty {};
+
+Empty emptyvar;
+
+int take_args(int a, ...) {
+ __builtin_va_list l;
+ __builtin_va_start(l, a);
+// CHECK: call void @llvm.va_start
+
+ emptyvar = __builtin_va_arg(l, Empty);
+// CHECK: load i8*, i8**
+// CHECK-NOT: getelementptr
+// CHECK: [[EMPTY_PTR:%[a-zA-Z0-9._]+]] = bitcast i8* {{%[a-zA-Z0-9._]+}} to %struct.Empty*
+
+ // It's conceivable that EMPTY_PTR may not actually be a valid pointer
+ // (e.g. it's at the very bottom of the stack and the next page is
+ // invalid). This doesn't matter provided it's never loaded (there's no
+ // well-defined way to tell), but it becomes a problem if we do try to use it.
+// CHECK-NOT: load %struct.Empty, %struct.Empty* [[EMPTY_PTR]]
+
+ int i = __builtin_va_arg(l, int);
+// CHECK: va_arg i8** {{%[a-zA-Z0-9._]+}}, i32
+
+ __builtin_va_end(l);
+ return i;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/arm64.cpp b/src/llvm-project/clang/test/CodeGenCXX/arm64.cpp
new file mode 100644
index 0000000..8043839
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/arm64.cpp
@@ -0,0 +1,122 @@
+// RUN: %clang_cc1 %s -triple=arm64-apple-ios -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=arm64-apple-ios -emit-llvm -o - | FileCheck -check-prefix=CHECK-GLOBALS %s
+
+// __cxa_guard_acquire argument is 64-bit
+// rdar://11540122
+struct A {
+ A();
+};
+
+void f() {
+ // CHECK: call i32 @__cxa_guard_acquire(i64*
+ static A a;
+}
+
+// ARM64 uses the C++11 definition of POD.
+// rdar://12650514
+namespace test1 {
+ // This class is POD in C++11 and cannot have objects allocated in
+ // its tail-padding.
+ struct ABase {};
+ struct A : ABase {
+ int x;
+ char c;
+ };
+
+ struct B : A {
+ char d;
+ };
+
+ int test() {
+ return sizeof(B);
+ }
+ // CHECK: define i32 @_ZN5test14testEv()
+ // CHECK: ret i32 12
+}
+
+namespace std {
+ class type_info;
+}
+
+// ARM64 uses string comparisons for what would otherwise be
+// default-visibility weak RTTI. rdar://12650568
+namespace test2 {
+ struct A {
+ virtual void foo();
+ };
+ void A::foo() {}
+ // CHECK-GLOBALS-DAG: @_ZTSN5test21AE = constant [11 x i8]
+ // CHECK-GLOBALS-DAG: @_ZTIN5test21AE = constant { {{.*}}, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @_ZTSN5test21AE, i32 0, i32 0) }
+
+ struct __attribute__((visibility("hidden"))) B {};
+ const std::type_info &b0 = typeid(B);
+ // CHECK-GLOBALS-DAG: @_ZTSN5test21BE = linkonce_odr hidden constant
+ // CHECK-GLOBALS-DAG: @_ZTIN5test21BE = linkonce_odr hidden constant { {{.*}}, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @_ZTSN5test21BE, i32 0, i32 0) }
+
+ const std::type_info &b1 = typeid(B*);
+ // CHECK-GLOBALS-DAG: @_ZTSPN5test21BE = linkonce_odr hidden constant
+ // CHECK-GLOBALS-DAG: @_ZTIPN5test21BE = linkonce_odr hidden constant { {{.*}}, i8* getelementptr inbounds ([12 x i8], [12 x i8]* @_ZTSPN5test21BE, i32 0, i32 0), i32 0, i8* bitcast
+
+ struct C {};
+ const std::type_info &c0 = typeid(C);
+ // CHECK-GLOBALS-DAG: @_ZTSN5test21CE = linkonce_odr hidden constant
+ // CHECK-GLOBALS-DAG: @_ZTIN5test21CE = linkonce_odr hidden constant { {{.*}}, i8* inttoptr (i64 add (i64 ptrtoint ([11 x i8]* @_ZTSN5test21CE to i64), i64 -9223372036854775808) to i8*) }
+
+ const std::type_info &c1 = typeid(C*);
+ // CHECK-GLOBALS-DAG: @_ZTSPN5test21CE = linkonce_odr hidden constant
+ // CHECK-GLOBALS-DAG: @_ZTIPN5test21CE = linkonce_odr hidden constant { {{.*}}, i8* inttoptr (i64 add (i64 ptrtoint ([12 x i8]* @_ZTSPN5test21CE to i64), i64 -9223372036854775808) to i8*), i32 0, i8* bitcast
+
+ // This class is explicitly-instantiated, but that instantiation
+ // doesn't guarantee to emit RTTI, so we can still demote the visibility.
+ template <class T> class D {};
+ template class D<int>;
+ const std::type_info &d0 = typeid(D<int>);
+ // CHECK-GLOBALS-DAG: @_ZTSN5test21DIiEE = linkonce_odr hidden constant
+ // CHECK-GLOBALS-DAG: @_ZTIN5test21DIiEE = linkonce_odr hidden constant { {{.*}}, i8* inttoptr (i64 add (i64 ptrtoint ([14 x i8]* @_ZTSN5test21DIiEE to i64), i64 -9223372036854775808) to i8*) }
+
+ // This class is explicitly-instantiated and *does* guarantee to
+ // emit RTTI, so we're stuck with having to use default visibility.
+ template <class T> class E {
+ virtual void foo() {}
+ };
+ template class E<int>;
+ // CHECK-GLOBALS-DAG: @_ZTSN5test21EIiEE = weak_odr constant [14 x i8]
+ // CHECK-GLOBALS-DAG: @_ZTIN5test21EIiEE = weak_odr constant { {{.*}}, i8* inttoptr (i64 add (i64 ptrtoint ([14 x i8]* @_ZTSN5test21EIiEE to i64), i64 -9223372036854775808) to i8*) }
+
+}
+
+// ARM64 reserves the top half of the vtable offset in virtual
+// member pointers.
+namespace test3 {
+ struct A {
+ virtual void foo();
+ virtual void bar();
+ };
+
+ // The offset half of the pointer is still initialized to zero.
+ // CHECK-GLOBALS-DAG: @_ZN5test34mptrE = global { i64, i64 } { i64 0, i64 1 }
+ void (A::*mptr)() = &A::foo;
+
+ // CHECK-LABEL: define void @_ZN5test34testEv()
+ // CHECK: [[TEMP:%.*]] = alloca [[A:.*]], align 8
+ // CHECK: [[MEMPTR:%.*]] = load { i64, i64 }, { i64, i64 }* @_ZN5test34mptrE, align 8
+ // CHECK: [[ADJUST_AND_IS_VIRTUAL:%.*]] = extractvalue { i64, i64 } [[MEMPTR]], 1
+ // CHECK: [[ADJUST:%.*]] = ashr i64 [[ADJUST_AND_IS_VIRTUAL]], 1
+ // CHECK: [[T0:%.*]] = bitcast [[A]]* [[TEMP]] to i8*
+ // CHECK: [[T1:%.*]] = getelementptr inbounds i8, i8* [[T0]], i64 [[ADJUST]]
+ // CHECK: [[ADJUSTED:%.*]] = bitcast i8* [[T1]] to [[A]]*
+ // CHECK: [[MEMBER:%.*]] = extractvalue { i64, i64 } [[MEMPTR]], 0
+ // CHECK: [[T0:%.*]] = and i64 [[ADJUST_AND_IS_VIRTUAL]], 1
+ // CHECK: [[IS_VIRTUAL:%.*]] = icmp ne i64 [[T0]], 0
+ // CHECK: br i1 [[IS_VIRTUAL]],
+ // CHECK: [[T0:%.*]] = bitcast [[A]]* [[ADJUSTED]] to i8**
+ // CHECK: [[VPTR:%.*]] = load i8*, i8** [[T0]], align 8
+ // CHECK: [[TRUNC:%.*]] = trunc i64 [[MEMBER]] to i32
+ // CHECK: [[ZEXT:%.*]] = zext i32 [[TRUNC]] to i64
+ // CHECK: [[T0:%.*]] = getelementptr i8, i8* [[VPTR]], i64 [[ZEXT]]
+ // CHECK: [[T1:%.*]] = bitcast i8* [[T0]] to void ([[A]]*)**
+ // CHECK: load void ([[A]]*)*, void ([[A]]*)** [[T1]],
+ void test() {
+ (A().*mptr)();
+ }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/armv7k.cpp b/src/llvm-project/clang/test/CodeGenCXX/armv7k.cpp
new file mode 100644
index 0000000..9b27b65
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/armv7k.cpp
@@ -0,0 +1,68 @@
+// RUN: %clang_cc1 %s -triple=thumbv7k-apple-watchos -emit-llvm -o - -target-abi aapcs16 | FileCheck %s
+// RUN: %clang_cc1 %s -triple=thumbv7k-apple-watchos -emit-llvm -o - -target-abi aapcs16 | FileCheck -check-prefix=CHECK-GLOBALS %s
+
+// __cxa_guard_acquire argument is 64-bit
+// rdar://11540122
+struct A {
+ A();
+};
+
+void f() {
+ // CHECK: call i32 @__cxa_guard_acquire(i32*
+ static A a;
+}
+
+// ARM64 uses the C++11 definition of POD.
+// rdar://12650514
+namespace test1 {
+ // This class is POD in C++11 and cannot have objects allocated in
+ // its tail-padding.
+ struct ABase {};
+ struct A : ABase {
+ int x;
+ char c;
+ };
+
+ struct B : A {
+ char d;
+ };
+
+ int test() {
+ return sizeof(B);
+ }
+ // CHECK: define i32 @_ZN5test14testEv()
+ // CHECK: ret i32 12
+}
+
+namespace std {
+ class type_info;
+}
+
+// ARM64 uses string comparisons for what would otherwise be
+// default-visibility weak RTTI. rdar://12650568
+namespace test2 {
+ struct A {
+ virtual void foo();
+ };
+ void A::foo() {}
+ // Tested below because these globals get kindof oddly rearranged.
+
+ struct __attribute__((visibility("hidden"))) B {};
+ const std::type_info &b0 = typeid(B);
+ // CHECK-GLOBALS: @_ZTSN5test21BE = linkonce_odr hidden constant
+ // CHECK-GLOBALS: @_ZTIN5test21BE = linkonce_odr hidden constant { {{.*}}, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @_ZTSN5test21BE, i32 0, i32 0) }
+
+ const std::type_info &b1 = typeid(B*);
+ // CHECK-GLOBALS: @_ZTSPN5test21BE = linkonce_odr hidden constant
+ // CHECK-GLOBALS: @_ZTIPN5test21BE = linkonce_odr hidden constant { {{.*}}, i8* getelementptr inbounds ([12 x i8], [12 x i8]* @_ZTSPN5test21BE, i32 0, i32 0), i32 0, i8* bitcast
+
+ struct C {};
+ const std::type_info &c0 = typeid(C);
+ // CHECK-GLOBALS: @_ZTSN5test21CE = linkonce_odr constant [11 x i8] c"N5test21CE\00"
+ // CHECK-GLOBALS: @_ZTIN5test21CE = linkonce_odr constant { {{.*}}, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @_ZTSN5test21CE, i32 0, i32 0) }
+}
+
+// va_list should be based on "char *" rather than "void *".
+
+// CHECK: define void @_Z11whatsVaListPc
+void whatsVaList(__builtin_va_list l) {}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/array-construction.cpp b/src/llvm-project/clang/test/CodeGenCXX/array-construction.cpp
new file mode 100644
index 0000000..53b81f2
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/array-construction.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm %s -o - | \
+// RUN: FileCheck %s
+// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -emit-llvm %s -o - | \
+// RUN: FileCheck %s
+
+extern "C" int printf(...);
+
+static int count;
+static float fcount;
+
+class xpto {
+public:
+ xpto() : i(count++), f(fcount++) {
+ printf("xpto::xpto()\n");
+ }
+ int i;
+ float f;
+
+ ~xpto() {
+ printf("xpto::~xpto()\n");
+ }
+};
+
+int main() {
+ xpto array[2][3][4];
+ for (int h = 0; h < 2; h++)
+ for (int i = 0; i < 3; i++)
+ for (int j = 0; j < 4; j++)
+ printf("array[%d][%d][%d] = {%d, %f}\n",
+ h, i, j, array[h][i][j].i, array[h][i][j].f);
+}
+
+// CHECK: call void @_ZN4xptoC1Ev
diff --git a/src/llvm-project/clang/test/CodeGenCXX/array-default-argument.cpp b/src/llvm-project/clang/test/CodeGenCXX/array-default-argument.cpp
new file mode 100644
index 0000000..23bc9fd
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/array-default-argument.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s -triple %itanium_abi_triple | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -o - %s -triple %itanium_abi_triple -std=c++98 -fexceptions -fcxx-exceptions | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-EH
+
+struct A {
+ A();
+ ~A();
+};
+
+struct B {
+ B(A = A());
+ ~B();
+};
+
+void f();
+// CHECK-LABEL: define {{(dso_local )?}}void @_Z1gv()
+void g() {
+ // CHECK: br label %[[LOOP:.*]]
+
+ // [[LOOP]]:
+ // CHECK: {{call|invoke}} {{.*}} @_ZN1AC1Ev([[TEMPORARY:.*]])
+ // CHECK-EH: unwind label %[[PARTIAL_ARRAY_LPAD:.*]]
+ // CHECK: {{call|invoke}} {{.*}} @_ZN1BC1E1A({{.*}}, [[TEMPORARY]])
+ // CHECK-EH: unwind label %[[A_AND_PARTIAL_ARRAY_LPAD:.*]]
+ // CHECK: {{call|invoke}} {{.*}} @_ZN1AD1Ev([[TEMPORARY]])
+ // CHECK-EH: unwind label %[[PARTIAL_ARRAY_LPAD]]
+ // CHECK: getelementptr {{.*}}, i{{[0-9]*}} 1
+ // CHECK: icmp eq
+ // CHECK: br i1 {{.*}} label %[[LOOP]]
+ B b[5];
+
+ // CHECK: {{call|invoke}} void @_Z1fv()
+ f();
+
+ // CHECK-NOT: @_ZN1AD1Ev(
+ // CHECK: {{call|invoke}} {{.*}} @_ZN1BD1Ev(
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/array-operator-delete-call.cpp b/src/llvm-project/clang/test/CodeGenCXX/array-operator-delete-call.cpp
new file mode 100644
index 0000000..890b142
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/array-operator-delete-call.cpp
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm %s -o - | \
+// RUN: FileCheck %s
+// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -emit-llvm %s -o - | \
+// RUN: FileCheck %s
+
+extern "C" int printf(...);
+
+int count;
+
+struct S {
+ S() : iS (++count) { printf("S::S(%d)\n", iS); }
+ ~S() { printf("S::~S(%d)\n", iS); }
+ int iS;
+};
+
+struct V {
+ V() : iV (++count) { printf("V::V(%d)\n", iV); }
+ virtual ~V() { printf("V::~V(%d)\n", iV); }
+ int iV;
+};
+
+struct COST
+{
+ S *cost;
+ V *vcost;
+ unsigned *cost_val;
+
+ ~COST();
+ COST();
+};
+
+
+COST::COST()
+{
+ cost = new S[3];
+ vcost = new V[4];
+ cost_val = new unsigned[10];
+}
+
+COST::~COST()
+{
+ if (cost) {
+ delete [] cost;
+ }
+ if (vcost) {
+ delete [] vcost;
+ }
+ if (cost_val)
+ delete [] cost_val;
+}
+
+COST c1;
+
+int main()
+{
+ COST c3;
+}
+COST c2;
+
+// CHECK: call void @_ZdaPv
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/array-pointer-decay.cpp b/src/llvm-project/clang/test/CodeGenCXX/array-pointer-decay.cpp
new file mode 100644
index 0000000..3fe6b72
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/array-pointer-decay.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 %s -emit-llvm -o -
+
+void f(const char*);
+
+void g() {
+ f("hello");
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/array-value-initialize.cpp b/src/llvm-project/clang/test/CodeGenCXX/array-value-initialize.cpp
new file mode 100644
index 0000000..27607c1
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/array-value-initialize.cpp
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - %s
+// RUN: %clang_cc1 -triple i386-apple-darwin -emit-llvm -o - %s
+
+// PR5463
+extern "C" int printf(...);
+
+struct S {
+ double filler;
+};
+
+struct Foo {
+ Foo(void) : bar_(), dbar_(), sbar_() {
+ for (int i = 0; i < 5; i++) {
+ printf("bar_[%d] = %d\n", i, bar_[i]);
+ printf("dbar_[%d] = %f\n", i, dbar_[i]);
+ printf("sbar_[%d].filler = %f\n", i, sbar_[i].filler);
+ }
+ }
+
+ int bar_[5];
+ double dbar_[5];
+ S sbar_[5];
+};
+
+int test1(void) {
+ Foo a;
+}
+
+// PR7063
+
+
+struct Unit
+{
+ Unit() {}
+ Unit(const Unit& v) {}
+};
+
+
+struct Stuff
+{
+ Unit leafPos[1];
+};
+
+
+int main()
+{
+
+ Stuff a;
+ Stuff b = a;
+
+ return 0;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/asm.cpp b/src/llvm-project/clang/test/CodeGenCXX/asm.cpp
new file mode 100644
index 0000000..3b745a7
--- /dev/null
+++ b/src/llvm-project/clang/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/src/llvm-project/clang/test/CodeGenCXX/assign-construct-memcpy.cpp b/src/llvm-project/clang/test/CodeGenCXX/assign-construct-memcpy.cpp
new file mode 100644
index 0000000..5e52b16
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/assign-construct-memcpy.cpp
@@ -0,0 +1,89 @@
+/// RUN: %clang_cc1 -triple x86_64-apple-darwin12 -emit-llvm -o - -std=c++11 %s -DPOD | FileCheck %s -check-prefix=CHECK-POD
+// RUN: %clang_cc1 -triple x86_64-apple-darwin12 -emit-llvm -o - -std=c++11 %s | FileCheck %s -check-prefix=CHECK-NONPOD
+
+// Declare the reserved placement operators.
+typedef __typeof__(sizeof(0)) size_t;
+void *operator new(size_t, void*) throw();
+void operator delete(void*, void*) throw();
+void *operator new[](size_t, void*) throw();
+void operator delete[](void*, void*) throw();
+template<typename T> T &&move(T&);
+
+struct foo {
+#ifndef POD
+ foo() {} // non-POD
+#endif
+ void *a, *b;
+ bool c;
+};
+
+// It is not legal to copy the tail padding in all cases, but if it is it can
+// yield better codegen.
+
+foo *test1(void *f, const foo &x) {
+ return new (f) foo(x);
+// CHECK-POD: test1
+// CHECK-POD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 8 {{.*}} align 8 {{.*}}i64 24
+
+// CHECK-NONPOD: test1
+// CHECK-NONPOD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 8 {{.*}} align 8 {{.*}}i64 24
+}
+
+foo *test2(const foo &x) {
+ return new foo(x);
+// CHECK-POD: test2
+// CHECK-POD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 16 {{.*}} align 8 {{.*}}i64 24
+
+// CHECK-NONPOD: test2
+// CHECK-NONPOD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 16 {{.*}} align 8 {{.*}}i64 24
+}
+
+foo test3(const foo &x) {
+ foo f = x;
+ return f;
+// CHECK-POD: test3
+// CHECK-POD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 8 {{.*}} align 8 {{.*}}i64 24
+
+// CHECK-NONPOD: test3
+// CHECK-NONPOD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 8 {{.*}} align 8 {{.*}}i64 24
+}
+
+foo *test4(foo &&x) {
+ return new foo(x);
+// CHECK-POD: test4
+// CHECK-POD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 16 {{.*}} align 8 {{.*}}i64 24
+
+// CHECK-NONPOD: test4
+// CHECK-NONPOD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 16 {{.*}} align 8 {{.*}}i64 24
+}
+
+void test5(foo &f, const foo &x) {
+ f = x;
+// CHECK-POD: test5
+// CHECK-POD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 8 {{.*}} align 8 {{.*}}i64 24
+
+// CHECK-NONPOD: test5
+// CHECK-NONPOD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 8 {{.*}} align 8 {{.*}}i64 17
+}
+
+extern foo globtest;
+
+void test6(foo &&x) {
+ globtest = move(x);
+// CHECK-POD: test6
+// CHECK-POD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 8 {{.*}} align 8 {{.*}}i64 24
+
+// CHECK-NONPOD: test6
+// CHECK-NONPOD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 8 {{.*}} align 8 {{.*}}i64 17
+}
+
+void byval(foo f);
+
+void test7(const foo &x) {
+ byval(x);
+// CHECK-POD: test7
+// CHECK-POD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 8 {{.*}} align 8 {{.*}}i64 24
+
+// CHECK-NONPOD: test7
+// CHECK-NONPOD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 8 {{.*}} align 8 {{.*}}i64 24
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/assign-operator.cpp b/src/llvm-project/clang/test/CodeGenCXX/assign-operator.cpp
new file mode 100644
index 0000000..40695b7
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/assign-operator.cpp
@@ -0,0 +1,54 @@
+// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o - -std=c++11 |FileCheck %s
+
+class x {
+public: int operator=(int);
+};
+void a() {
+ x a;
+ a = 1u;
+}
+
+void f(int i, int j) {
+ // CHECK: load i32
+ // CHECK: load i32
+ // CHECK: add nsw i32
+ // CHECK: store i32
+ // CHECK: store i32 17, i32
+ // CHECK: ret
+ (i += j) = 17;
+}
+
+// Taken from g++.old-deja/g++.jason/net.C
+namespace test1 {
+ template <class T> void fn (T t) { }
+ template <class T> struct A {
+ void (*p)(T);
+ A() { p = fn; }
+ };
+
+ A<int> a;
+}
+
+// Ensure that we use memcpy when we would have selected a trivial assignment
+// operator, even for a non-trivially-copyable type.
+struct A {
+ A &operator=(const A&);
+};
+struct B {
+ B(const B&);
+ B &operator=(const B&) = default;
+ int n;
+};
+struct C {
+ A a;
+ B b[16];
+};
+void b(C &a, C &b) {
+ // CHECK: define {{.*}} @_ZN1CaSERKS_(
+ // CHECK: call {{.*}} @_ZN1AaSERKS_(
+ // CHECK-NOT: call {{.*}} @_ZN1BaSERKS_(
+ // CHECK: call {{.*}} @{{.*}}memcpy
+ // CHECK-NOT: call {{.*}} @_ZN1BaSERKS_(
+ // CHECK: }
+ a = b;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/atomic-align.cpp b/src/llvm-project/clang/test/CodeGenCXX/atomic-align.cpp
new file mode 100644
index 0000000..9852ac3
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/atomic-align.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 %s -std=c++11 -emit-llvm -o - -triple=x86_64-linux-gnu | FileCheck %s
+
+struct AM {
+ int f1, f2;
+};
+alignas(8) AM m;
+AM load1() {
+ AM am;
+ // m is declared to align to 8bytes, so generate load atomic instead
+ // of libcall.
+ // CHECK-LABEL: @_Z5load1v
+ // CHECK: load atomic {{.*}} monotonic
+ __atomic_load(&m, &am, 0);
+ return am;
+}
+
+struct BM {
+ int f1;
+ alignas(8) AM f2;
+};
+BM bm;
+AM load2() {
+ AM am;
+ // BM::f2 is declared to align to 8bytes, so generate load atomic instead
+ // of libcall.
+ // CHECK-LABEL: @_Z5load2v
+ // CHECK: load atomic {{.*}} monotonic
+ __atomic_load(&bm.f2, &am, 0);
+ return am;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/atomic-dllexport.cpp b/src/llvm-project/clang/test/CodeGenCXX/atomic-dllexport.cpp
new file mode 100644
index 0000000..20c5005
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/atomic-dllexport.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -triple i686-windows-msvc -emit-llvm -std=c++11 -fms-extensions -O0 -o - %s | FileCheck --check-prefix=M32 %s
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c++11 -fms-extensions -O0 -o - %s | FileCheck --check-prefix=M64 %s
+
+struct __declspec(dllexport) SomeStruct {
+ // Copy assignment operator should be produced, and exported:
+ // M32: define weak_odr dso_local dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.SomeStruct* @"??4SomeStruct@@QAEAAU0@ABU0@@Z"
+ // M64: define weak_odr dso_local dllexport dereferenceable({{[0-9]+}}) %struct.SomeStruct* @"??4SomeStruct@@QEAAAEAU0@AEBU0@@Z"
+ _Atomic(int) mData;
+};
diff --git a/src/llvm-project/clang/test/CodeGenCXX/atomic-inline.cpp b/src/llvm-project/clang/test/CodeGenCXX/atomic-inline.cpp
new file mode 100644
index 0000000..fe72758
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/atomic-inline.cpp
@@ -0,0 +1,69 @@
+// RUN: %clang_cc1 %s -std=c++11 -emit-llvm -o - -triple=x86_64-linux-gnu | FileCheck %s
+// RUN: %clang_cc1 %s -std=c++11 -emit-llvm -o - -triple=x86_64-linux-gnu -target-cpu core2 | FileCheck %s --check-prefix=CORE2
+// Check the atomic code generation for cpu targets w/wo cx16 support.
+
+struct alignas(8) AM8 {
+ int f1, f2;
+};
+AM8 m8;
+AM8 load8() {
+ AM8 am;
+ // CHECK-LABEL: @_Z5load8v
+ // CHECK: load atomic i64, {{.*}} monotonic
+ // CORE2-LABEL: @_Z5load8v
+ // CORE2: load atomic i64, {{.*}} monotonic
+ __atomic_load(&m8, &am, 0);
+ return am;
+}
+
+AM8 s8;
+void store8() {
+ // CHECK-LABEL: @_Z6store8v
+ // CHECK: store atomic i64 {{.*}} monotonic
+ // CORE2-LABEL: @_Z6store8v
+ // CORE2: store atomic i64 {{.*}} monotonic
+ __atomic_store(&m8, &s8, 0);
+}
+
+bool cmpxchg8() {
+ AM8 am;
+ // CHECK-LABEL: @_Z8cmpxchg8v
+ // CHECK: cmpxchg i64* {{.*}} monotonic
+ // CORE2-LABEL: @_Z8cmpxchg8v
+ // CORE2: cmpxchg i64* {{.*}} monotonic
+ return __atomic_compare_exchange(&m8, &s8, &am, 0, 0, 0);
+}
+
+struct alignas(16) AM16 {
+ long f1, f2;
+};
+
+AM16 m16;
+AM16 load16() {
+ AM16 am;
+ // CHECK-LABEL: @_Z6load16v
+ // CHECK: call void @__atomic_load
+ // CORE2-LABEL: @_Z6load16v
+ // CORE2: load atomic i128, {{.*}} monotonic
+ __atomic_load(&m16, &am, 0);
+ return am;
+}
+
+AM16 s16;
+void store16() {
+ // CHECK-LABEL: @_Z7store16v
+ // CHECK: call void @__atomic_store
+ // CORE2-LABEL: @_Z7store16v
+ // CORE2: store atomic i128 {{.*}} monotonic
+ __atomic_store(&m16, &s16, 0);
+}
+
+bool cmpxchg16() {
+ AM16 am;
+ // CHECK-LABEL: @_Z9cmpxchg16v
+ // CHECK: call zeroext i1 @__atomic_compare_exchange
+ // CORE2-LABEL: @_Z9cmpxchg16v
+ // CORE2: cmpxchg i128* {{.*}} monotonic
+ return __atomic_compare_exchange(&m16, &s16, &am, 0, 0, 0);
+}
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/atomic.cpp b/src/llvm-project/clang/test/CodeGenCXX/atomic.cpp
new file mode 100644
index 0000000..653f16d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/atomic.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=i686-apple-darwin9 | FileCheck %s
+
+namespace PR11411 {
+ template<typename _Tp> struct Ptr {
+ void f();
+ };
+
+ // CHECK-LABEL: define linkonce_odr void @_ZN7PR114113PtrIiE1fEv
+ // CHECK-NOT: ret
+ template<typename _Tp> inline void Ptr<_Tp>::f() {
+ int* _refcount;
+ // CHECK: atomicrmw add i32*
+ __sync_fetch_and_add(_refcount, 1);
+ // CHECK-NEXT: ret void
+ }
+ void f(Ptr<int> *a) { a->f(); }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/atomicinit.cpp b/src/llvm-project/clang/test/CodeGenCXX/atomicinit.cpp
new file mode 100644
index 0000000..4c30ec3
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/atomicinit.cpp
@@ -0,0 +1,106 @@
+// RUN: %clang_cc1 %s -emit-llvm -O1 -o - -triple=i686-apple-darwin9 -std=c++11 | FileCheck %s
+
+// CHECK-DAG: @PR22043 = local_unnamed_addr global i32 0, align 4
+typedef _Atomic(int) AtomicInt;
+AtomicInt PR22043 = AtomicInt();
+
+// CHECK-DAG: @_ZN7PR180978constant1aE = local_unnamed_addr global { i16, i8 } { i16 1, i8 6 }, align 4
+// CHECK-DAG: @_ZN7PR180978constant1bE = local_unnamed_addr global { i16, i8 } { i16 2, i8 6 }, align 4
+// CHECK-DAG: @_ZN7PR180978constant1cE = local_unnamed_addr global { i16, i8 } { i16 3, i8 6 }, align 4
+// CHECK-DAG: @_ZN7PR180978constant1yE = local_unnamed_addr global { { i16, i8 }, i32 } { { i16, i8 } { i16 4, i8 6 }, i32 5 }, align 4
+
+struct A {
+ _Atomic(int) i;
+ A(int j);
+ void v(int j);
+};
+// Storing to atomic values should be atomic
+// CHECK: store atomic i32
+void A::v(int j) { i = j; }
+// Initialising atomic values should not be atomic
+// CHECK-NOT: store atomic
+A::A(int j) : i(j) {}
+
+struct B {
+ int i;
+ B(int x) : i(x) {}
+};
+
+_Atomic(B) b;
+
+// CHECK-LABEL: define void @_Z11atomic_initR1Ai
+void atomic_init(A& a, int i) {
+ // CHECK-NOT: atomic
+ // CHECK: tail call void @_ZN1BC1Ei
+ __c11_atomic_init(&b, B(i));
+ // CHECK-NEXT: ret void
+}
+
+// CHECK-LABEL: define void @_Z16atomic_init_boolPU7_Atomicbb
+void atomic_init_bool(_Atomic(bool) *ab, bool b) {
+ // CHECK-NOT: atomic
+ // CHECK: {{zext i1.*to i8}}
+ // CHECK-NEXT: store i8
+ __c11_atomic_init(ab, b);
+ // CHECK-NEXT: ret void
+}
+
+struct AtomicBoolMember {
+ _Atomic(bool) ab;
+ AtomicBoolMember(bool b);
+};
+
+// CHECK-LABEL: define void @_ZN16AtomicBoolMemberC2Eb
+// CHECK: zext i1 {{.*}} to i8
+// CHECK: store i8
+// CHECK-NEXT: ret void
+AtomicBoolMember::AtomicBoolMember(bool b) : ab(b) { }
+
+namespace PR18097 {
+ namespace dynamic {
+ struct X {
+ X(int);
+ short n;
+ char c;
+ };
+
+ // CHECK-LABEL: define {{.*}} @__cxx_global_var_init
+ // CHECK: call void @_ZN7PR180977dynamic1XC1Ei({{.*}}* nonnull @_ZN7PR180977dynamic1aE, i32 1)
+ _Atomic(X) a = X(1);
+
+ // CHECK-LABEL: define {{.*}} @__cxx_global_var_init
+ // CHECK: call void @_ZN7PR180977dynamic1XC1Ei({{.*}}* nonnull @_ZN7PR180977dynamic1bE, i32 2)
+ _Atomic(X) b(X(2));
+
+ // CHECK-LABEL: define {{.*}} @__cxx_global_var_init
+ // CHECK: call void @_ZN7PR180977dynamic1XC1Ei({{.*}}* nonnull @_ZN7PR180977dynamic1cE, i32 3)
+ _Atomic(X) c{X(3)};
+
+ struct Y {
+ _Atomic(X) a;
+ _Atomic(int) b;
+ };
+ // CHECK-LABEL: define {{.*}} @__cxx_global_var_init
+ // CHECK: call void @_ZN7PR180977dynamic1XC1Ei({{.*}}* getelementptr inbounds ({{.*}}, {{.*}}* @_ZN7PR180977dynamic1yE, i32 0, i32 0), i32 4)
+ // CHECK: store i32 5, i32* getelementptr inbounds ({{.*}}, {{.*}}* @_ZN7PR180977dynamic1yE, i32 0, i32 1)
+ Y y = { X(4), 5 };
+ }
+
+ // CHECKs at top of file.
+ namespace constant {
+ struct X {
+ constexpr X(int n) : n(n) {}
+ short n;
+ char c = 6;
+ };
+ _Atomic(X) a = X(1);
+ _Atomic(X) b(X(2));
+ _Atomic(X) c{X(3)};
+
+ struct Y {
+ _Atomic(X) a;
+ _Atomic(int) b;
+ };
+ Y y = { X(4), 5 };
+ }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/attr-cleanup.cpp b/src/llvm-project/clang/test/CodeGenCXX/attr-cleanup.cpp
new file mode 100644
index 0000000..5ece41a
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/attr-cleanup.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -o - %s | FileCheck %s
+
+namespace N {
+ void free(void *i) {}
+}
+
+int main(void) {
+ // CHECK: call {{.*}}void @_ZN1N4freeEPv
+ void *fp __attribute__((cleanup(N::free)));
+ return 0;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/attr-cpuspecific.cpp b/src/llvm-project/clang/test/CodeGenCXX/attr-cpuspecific.cpp
new file mode 100644
index 0000000..bfee49c
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/attr-cpuspecific.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,LINUX
+// RUN: %clang_cc1 -triple x86_64-windows-pc -fms-compatibility -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,WINDOWS
+
+struct S {
+ __attribute__((cpu_specific(atom)))
+ void Func(){}
+ __attribute__((cpu_dispatch(ivybridge,atom)))
+ void Func(){}
+};
+
+void foo() {
+ S s;
+ s.Func();
+}
+
+// LINUX: define void (%struct.S*)* @_ZN1S4FuncEv.resolver
+// LINUX: ret void (%struct.S*)* @_ZN1S4FuncEv.S
+// LINUX: ret void (%struct.S*)* @_ZN1S4FuncEv.O
+// LINUX: declare void @_ZN1S4FuncEv.S
+// LINUX: define linkonce_odr void @_ZN1S4FuncEv.O
+
+// WINDOWS: define dso_local void @"?Func@S@@QEAAXXZ"(%struct.S*)
+// WINDOWS: musttail call void @"?Func@S@@QEAAXXZ.S"(%struct.S* %0)
+// WINDOWS: musttail call void @"?Func@S@@QEAAXXZ.O"(%struct.S* %0)
+// WINDOWS: declare dso_local void @"?Func@S@@QEAAXXZ.S"
+// WINDOWS: define linkonce_odr dso_local void @"?Func@S@@QEAAXXZ.O"
diff --git a/src/llvm-project/clang/test/CodeGenCXX/attr-disable-tail-calls.cpp b/src/llvm-project/clang/test/CodeGenCXX/attr-disable-tail-calls.cpp
new file mode 100644
index 0000000..b9a3c27
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/attr-disable-tail-calls.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -triple=x86_64-apple-darwin -std=c++11 -emit-llvm -o - %s | FileCheck %s
+
+class B {
+public:
+ [[clang::disable_tail_calls]] virtual int m1() { return 1; }
+ virtual int m2() { return 2; }
+ int m3() { return 3; }
+ [[clang::disable_tail_calls]] int m4();
+};
+
+class D : public B {
+public:
+ int m1() override { return 11; }
+ [[clang::disable_tail_calls]] int m2() override { return 22; }
+};
+
+int foo1() {
+ B *b = new B;
+ D *d = new D;
+ int t = 0;
+ t += b->m1() + b->m2() + b->m3() + b->m4();
+ t += d->m1() + d->m2();
+ return t;
+}
+
+// CHECK: define linkonce_odr i32 @_ZN1B2m3Ev(%class.B* %this) [[ATTRFALSE:#[0-9]+]]
+// CHECK: declare i32 @_ZN1B2m4Ev(%class.B*) [[ATTRTRUE0:#[0-9]+]]
+// CHECK: define linkonce_odr i32 @_ZN1B2m1Ev(%class.B* %this) unnamed_addr [[ATTRTRUE1:#[0-9]+]]
+// CHECK: define linkonce_odr i32 @_ZN1B2m2Ev(%class.B* %this) unnamed_addr [[ATTRFALSE:#[0-9]+]]
+// CHECK: define linkonce_odr i32 @_ZN1D2m1Ev(%class.D* %this) unnamed_addr [[ATTRFALSE:#[0-9]+]]
+// CHECK: define linkonce_odr i32 @_ZN1D2m2Ev(%class.D* %this) unnamed_addr [[ATTRTRUE1:#[0-9]+]]
+
+// CHECK: attributes [[ATTRFALSE]] = { {{.*}}"disable-tail-calls"="false"{{.*}} }
+// CHECK: attributes [[ATTRTRUE0]] = { {{.*}}"disable-tail-calls"="true"{{.*}} }
+// CHECK: attributes [[ATTRTRUE1]] = { {{.*}}"disable-tail-calls"="true"{{.*}} }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/attr-exclude_from_explicit_instantiation.dont_assume_extern_instantiation.cpp b/src/llvm-project/clang/test/CodeGenCXX/attr-exclude_from_explicit_instantiation.dont_assume_extern_instantiation.cpp
new file mode 100644
index 0000000..efbbb0c
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/attr-exclude_from_explicit_instantiation.dont_assume_extern_instantiation.cpp
@@ -0,0 +1,84 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -O0 -o - %s | FileCheck %s
+
+// Test that we do not assume that entities marked with the
+// exclude_from_explicit_instantiation attribute are instantiated
+// in another TU when an extern template instantiation declaration
+// is present. We test that by making sure that definitions are
+// generated in this TU despite there being an extern template
+// instantiation declaration, which is normally not the case.
+
+#define EXCLUDE_FROM_EXPLICIT_INSTANTIATION __attribute__((exclude_from_explicit_instantiation))
+
+template <class T>
+struct Foo {
+ EXCLUDE_FROM_EXPLICIT_INSTANTIATION inline void non_static_member_function1();
+ EXCLUDE_FROM_EXPLICIT_INSTANTIATION void non_static_member_function2();
+
+ EXCLUDE_FROM_EXPLICIT_INSTANTIATION static inline void static_member_function1();
+ EXCLUDE_FROM_EXPLICIT_INSTANTIATION static void static_member_function2();
+
+ EXCLUDE_FROM_EXPLICIT_INSTANTIATION static int static_data_member;
+
+ struct EXCLUDE_FROM_EXPLICIT_INSTANTIATION member_class1 {
+ static void static_member_function() { }
+ };
+
+ struct member_class2 {
+ EXCLUDE_FROM_EXPLICIT_INSTANTIATION static void static_member_function() { }
+ };
+};
+
+template <class T> inline void Foo<T>::non_static_member_function1() { }
+template <class T> void Foo<T>::non_static_member_function2() { }
+
+template <class T> inline void Foo<T>::static_member_function1() { }
+template <class T> void Foo<T>::static_member_function2() { }
+
+template <class T> int Foo<T>::static_data_member = 0;
+
+extern template struct Foo<int>;
+
+void use() {
+ Foo<int> f;
+
+ // An inline non-static member function marked with the attribute is not
+ // part of the extern template declaration, so a definition must be emitted
+ // in this TU.
+ // CHECK-DAG: define linkonce_odr void @_ZN3FooIiE27non_static_member_function1Ev
+ f.non_static_member_function1();
+
+ // A non-inline non-static member function marked with the attribute is
+ // not part of the extern template declaration, so a definition must be
+ // emitted in this TU.
+ // CHECK-DAG: define linkonce_odr void @_ZN3FooIiE27non_static_member_function2Ev
+ f.non_static_member_function2();
+
+ // An inline static member function marked with the attribute is not
+ // part of the extern template declaration, so a definition must be
+ // emitted in this TU.
+ // CHECK-DAG: define linkonce_odr void @_ZN3FooIiE23static_member_function1Ev
+ Foo<int>::static_member_function1();
+
+ // A non-inline static member function marked with the attribute is not
+ // part of the extern template declaration, so a definition must be
+ // emitted in this TU.
+ // CHECK-DAG: define linkonce_odr void @_ZN3FooIiE23static_member_function2Ev
+ Foo<int>::static_member_function2();
+
+ // A static data member marked with the attribute is not part of the
+ // extern template declaration, so a definition must be emitted in this TU.
+ // CHECK-DAG: @_ZN3FooIiE18static_data_memberE = linkonce_odr global
+ int& odr_use = Foo<int>::static_data_member;
+
+ // A member class marked with the attribute is not part of the extern
+ // template declaration (it is not recursively instantiated), so its member
+ // functions must be emitted in this TU.
+ // CHECK-DAG: define linkonce_odr void @_ZN3FooIiE13member_class122static_member_functionEv
+ Foo<int>::member_class1::static_member_function();
+
+ // A member function marked with the attribute in a member class is not
+ // part of the extern template declaration of the parent class template, so
+ // it must be emitted in this TU.
+ // CHECK-DAG: define linkonce_odr void @_ZN3FooIiE13member_class222static_member_functionEv
+ Foo<int>::member_class2::static_member_function();
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/attr-mode-vector-types-tmpl.cpp b/src/llvm-project/clang/test/CodeGenCXX/attr-mode-vector-types-tmpl.cpp
new file mode 100644
index 0000000..6373cf0
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/attr-mode-vector-types-tmpl.cpp
@@ -0,0 +1,108 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu %s -emit-llvm -o - | FileCheck %s
+
+template <class T>
+void CheckIntScalarTypes() {
+ // T will be substituted with 'int' and 'enum' types.
+
+ typedef T __attribute__((mode(QI))) T1;
+ typedef T __attribute__((mode(HI))) T2;
+ typedef T __attribute__((mode(SI))) T3;
+ typedef T __attribute__((mode(DI))) T4;
+
+ T1 a1;
+ T2 a2;
+ T3 a3;
+ T4 a4;
+}
+
+template <class T>
+void CheckIntVectorTypes() {
+ // T will be substituted with 'int'.
+
+ typedef int __attribute__((mode(QI))) __attribute__((vector_size(8))) VT_11;
+ typedef T __attribute__((mode(V8QI))) VT_12;
+ typedef int __attribute__((mode(SI))) __attribute__((vector_size(16))) VT_21;
+ typedef T __attribute__((mode(V4SI))) VT_22;
+ typedef int __attribute__((mode(DI))) __attribute__((vector_size(64))) VT_31;
+ typedef T __attribute__((mode(V8DI))) VT_32;
+
+ VT_11 v11;
+ VT_12 v12;
+
+ VT_21 v21;
+ VT_22 v22;
+
+ VT_31 v31;
+ VT_32 v32;
+}
+
+template <class T>
+void CheckFloatVectorTypes() {
+ // T will be substituted with 'float'.
+
+ typedef float __attribute__((mode(SF))) __attribute__((vector_size(128))) VT_41;
+ typedef T __attribute__((mode(V32SF))) VT_42;
+ typedef float __attribute__((mode(DF))) __attribute__((vector_size(256))) VT_51;
+ typedef T __attribute__((mode(V32DF))) VT_52;
+
+ VT_41 v41;
+ VT_42 v42;
+
+ VT_51 v51;
+ VT_52 v52;
+}
+
+template <class T>
+void CheckInstantiationWithModedType() {
+ T x1;
+}
+
+typedef enum { A1, B1 } EnumTy;
+typedef int __attribute__((mode(DI))) Int64Ty1;
+typedef enum __attribute__((mode(DI))) { A2 } Int64Ty2;
+typedef int __attribute__((mode(V8HI))) IntVecTy1;
+
+void test() {
+
+ // CHECK: define {{.*}} void @_Z19CheckIntScalarTypesIiEvv()
+ // CHECK: %{{.+}} = alloca i8
+ // CHECK: %{{.+}} = alloca i16
+ // CHECK: %{{.+}} = alloca i32
+ // CHECK: %{{.+}} = alloca i64
+ CheckIntScalarTypes<int>();
+
+ // CHECK: define {{.*}} void @_Z19CheckIntScalarTypesI6EnumTyEvv()
+ // CHECK: %{{.+}} = alloca i8
+ // CHECK: %{{.+}} = alloca i16
+ // CHECK: %{{.+}} = alloca i32
+ // CHECK: %{{.+}} = alloca i64
+ CheckIntScalarTypes<EnumTy>();
+
+ // CHECK: define {{.*}} void @_Z19CheckIntVectorTypesIiEvv()
+ // CHECK: %{{.+}} = alloca <8 x i8>
+ // CHECK: %{{.+}} = alloca <8 x i8>
+ // CHECK: %{{.+}} = alloca <4 x i32>
+ // CHECK: %{{.+}} = alloca <4 x i32>
+ // CHECK: %{{.+}} = alloca <8 x i64>
+ // CHECK: %{{.+}} = alloca <8 x i64>
+ CheckIntVectorTypes<int>();
+
+ // CHECK: define {{.*}} void @_Z21CheckFloatVectorTypesIfEvv()
+ // CHECK: %{{.+}} = alloca <32 x float>
+ // CHECK: %{{.+}} = alloca <32 x float>
+ // CHECK: %{{.+}} = alloca <32 x double>
+ // CHECK: %{{.+}} = alloca <32 x double>
+ CheckFloatVectorTypes<float>();
+
+ // CHECK: define {{.*}} void @_Z31CheckInstantiationWithModedTypeIlEvv()
+ // CHECK: [[X1:%.+]] = alloca i64
+ CheckInstantiationWithModedType<Int64Ty1>();
+
+ // CHECK: define {{.*}} void @_Z31CheckInstantiationWithModedTypeI8Int64Ty2Evv()
+ // CHECK: [[X1]] = alloca i64
+ CheckInstantiationWithModedType<Int64Ty2>();
+
+ // CHECK: define {{.*}} void @_Z31CheckInstantiationWithModedTypeIDv8_sEvv()
+ // CHECK: [[X1]] = alloca <8 x i16>
+ CheckInstantiationWithModedType<IntVecTy1>();
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/attr-no-destroy-d54344.cpp b/src/llvm-project/clang/test/CodeGenCXX/attr-no-destroy-d54344.cpp
new file mode 100644
index 0000000..2e004d6
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/attr-no-destroy-d54344.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -std=c++2a -emit-llvm -O0 -triple x86_64-unknown-linux-gnu -DNOATTR %s -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++2a -emit-llvm -O0 -triple x86_64-unknown-linux-gnu %s -o - | FileCheck %s --check-prefix=CHECK-ATTR
+// RUN: %clang_cc1 -std=c++2a -emit-llvm -O0 -triple x86_64-unknown-linux-gnu -DNOATTR -fno-c++-static-destructors %s -o - | FileCheck %s --check-prefix=CHECK-FLAG
+
+// Regression test for D54344. Class with no user-defined destructor
+// that has an inherited member that has a non-trivial destructor
+// and a non-default constructor will attempt to emit a destructor
+// despite being marked as __attribute((no_destroy)) in which case
+// it would trigger an assertion due to an incorrect assumption.
+
+// This test is more reliable with asserts to work as without
+// the crash may (unlikely) could generate working but semantically
+// incorrect code.
+
+class a {
+public:
+ ~a();
+};
+class logger_base {
+ a d;
+};
+class e : logger_base {};
+#ifndef NOATTR
+__attribute((no_destroy))
+#endif
+e g;
+
+// In the absence of the attribute and flag, both ctor and dtor should
+// be emitted, check for that.
+// CHECK: @__cxx_global_var_init
+// CHECK: @__cxa_atexit
+
+// When attribute is enabled, the constructor should not be balanced
+// by a destructor. Make sure we have the ctor but not the dtor
+// registration.
+// CHECK-ATTR: @__cxx_global_var_init
+// CHECK-ATTR-NOT: @__cxa_atexit
+
+// Same scenario except with global flag (-fno-c++-static-destructors)
+// supressing it instead of the attribute.
+// CHECK-FLAG: @__cxx_global_var_init
+// CHECK-FLAG-NOT: @__cxa_atexit
diff --git a/src/llvm-project/clang/test/CodeGenCXX/attr-notail.cpp b/src/llvm-project/clang/test/CodeGenCXX/attr-notail.cpp
new file mode 100644
index 0000000..80af424
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/attr-notail.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -triple=x86_64-apple-darwin -std=c++11 -emit-llvm -o - %s | FileCheck %s
+
+class Class1 {
+public:
+ [[clang::not_tail_called]] int m1();
+ int m2();
+};
+
+int foo1(int a, Class1 *c1) {
+ if (a)
+ return c1->m1();
+ return c1->m2();
+}
+
+// CHECK-LABEL: define i32 @_Z4foo1iP6Class1(
+// CHECK: %{{[a-z0-9]+}} = notail call i32 @_ZN6Class12m1Ev(%class.Class1*
+// CHECK: %{{[a-z0-9]+}} = call i32 @_ZN6Class12m2Ev(%class.Class1*
diff --git a/src/llvm-project/clang/test/CodeGenCXX/attr-target-mv-diff-ns.cpp b/src/llvm-project/clang/test/CodeGenCXX/attr-target-mv-diff-ns.cpp
new file mode 100644
index 0000000..77e1ad7
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/attr-target-mv-diff-ns.cpp
@@ -0,0 +1,88 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix=LINUX
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows-pc -emit-llvm %s -o - | FileCheck %s --check-prefix=WINDOWS
+// Test ensures that this properly differentiates between types in different
+// namespaces.
+int __attribute__((target("sse4.2"))) foo(int) { return 0; }
+int __attribute__((target("arch=sandybridge"))) foo(int);
+int __attribute__((target("arch=ivybridge"))) foo(int) {return 1;}
+int __attribute__((target("default"))) foo(int) { return 2; }
+
+namespace ns {
+int __attribute__((target("sse4.2"))) foo(int) { return 0; }
+int __attribute__((target("arch=sandybridge"))) foo(int);
+int __attribute__((target("arch=ivybridge"))) foo(int) {return 1;}
+int __attribute__((target("default"))) foo(int) { return 2; }
+}
+
+int bar() {
+ return foo(1) + ns::foo(2);
+}
+
+// LINUX: @_Z3fooi.ifunc = ifunc i32 (i32), i32 (i32)* ()* @_Z3fooi.resolver
+// LINUX: @_ZN2ns3fooEi.ifunc = ifunc i32 (i32), i32 (i32)* ()* @_ZN2ns3fooEi.resolver
+
+// LINUX: define i32 @_Z3fooi.sse4.2(i32)
+// LINUX: ret i32 0
+// LINUX: define i32 @_Z3fooi.arch_ivybridge(i32)
+// LINUX: ret i32 1
+// LINUX: define i32 @_Z3fooi(i32)
+// LINUX: ret i32 2
+
+// WINDOWS: define dso_local i32 @"?foo@@[email protected]"(i32)
+// WINDOWS: ret i32 0
+// WINDOWS: define dso_local i32 @"?foo@@[email protected]_ivybridge"(i32)
+// WINDOWS: ret i32 1
+// WINDOWS: define dso_local i32 @"?foo@@YAHH@Z"(i32)
+// WINDOWS: ret i32 2
+
+// LINUX: define i32 @_ZN2ns3fooEi.sse4.2(i32)
+// LINUX: ret i32 0
+// LINUX: define i32 @_ZN2ns3fooEi.arch_ivybridge(i32)
+// LINUX: ret i32 1
+// LINUX: define i32 @_ZN2ns3fooEi(i32)
+// LINUX: ret i32 2
+
+// WINDOWS: define dso_local i32 @"?foo@ns@@[email protected]"(i32)
+// WINDOWS: ret i32 0
+// WINDOWS: define dso_local i32 @"?foo@ns@@[email protected]_ivybridge"(i32)
+// WINDOWS: ret i32 1
+// WINDOWS: define dso_local i32 @"?foo@ns@@YAHH@Z"(i32)
+// WINDOWS: ret i32 2
+
+// LINUX: define i32 @_Z3barv()
+// LINUX: call i32 @_Z3fooi.ifunc(i32 1)
+// LINUX: call i32 @_ZN2ns3fooEi.ifunc(i32 2)
+
+// WINDOWS: define dso_local i32 @"?bar@@YAHXZ"()
+// WINDOWS: call i32 @"?foo@@[email protected]"(i32 1)
+// WINDOWS: call i32 @"?foo@ns@@[email protected]"(i32 2)
+
+// LINUX: define i32 (i32)* @_Z3fooi.resolver() comdat
+// LINUX: ret i32 (i32)* @_Z3fooi.arch_sandybridge
+// LINUX: ret i32 (i32)* @_Z3fooi.arch_ivybridge
+// LINUX: ret i32 (i32)* @_Z3fooi.sse4.2
+// LINUX: ret i32 (i32)* @_Z3fooi
+
+// WINDOWS: define dso_local i32 @"?foo@@[email protected]"(i32) comdat
+// WINDOWS: call i32 @"?foo@@[email protected]_sandybridge"(i32 %0)
+// WINDOWS: call i32 @"?foo@@[email protected]_ivybridge"(i32 %0)
+// WINDOWS: call i32 @"?foo@@[email protected]"(i32 %0)
+// WINDOWS: call i32 @"?foo@@YAHH@Z"(i32 %0)
+
+// LINUX: define i32 (i32)* @_ZN2ns3fooEi.resolver() comdat
+// LINUX: ret i32 (i32)* @_ZN2ns3fooEi.arch_sandybridge
+// LINUX: ret i32 (i32)* @_ZN2ns3fooEi.arch_ivybridge
+// LINUX: ret i32 (i32)* @_ZN2ns3fooEi.sse4.2
+// LINUX: ret i32 (i32)* @_ZN2ns3fooEi
+
+// WINDOWS: define dso_local i32 @"?foo@ns@@[email protected]"(i32) comdat
+// WINDOWS: call i32 @"?foo@ns@@[email protected]_sandybridge"(i32 %0)
+// WINDOWS: call i32 @"?foo@ns@@[email protected]_ivybridge"(i32 %0)
+// WINDOWS: call i32 @"?foo@ns@@[email protected]"(i32 %0)
+// WINDOWS: call i32 @"?foo@ns@@YAHH@Z"(i32 %0)
+
+// LINUX: declare i32 @_Z3fooi.arch_sandybridge(i32)
+// LINUX: declare i32 @_ZN2ns3fooEi.arch_sandybridge(i32)
+
+// WINDOWS: declare dso_local i32 @"?foo@@[email protected]_sandybridge"(i32)
+// WINDOWS: declare dso_local i32 @"?foo@ns@@[email protected]_sandybridge"(i32)
diff --git a/src/llvm-project/clang/test/CodeGenCXX/attr-target-mv-func-ptrs.cpp b/src/llvm-project/clang/test/CodeGenCXX/attr-target-mv-func-ptrs.cpp
new file mode 100644
index 0000000..6336e19
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/attr-target-mv-func-ptrs.cpp
@@ -0,0 +1,54 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix=LINUX
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows-pc -emit-llvm %s -o - | FileCheck %s --check-prefix=WINDOWS
+void temp();
+void temp(int);
+using FP = void(*)(int);
+void b() {
+ FP f = temp;
+}
+
+int __attribute__((target("sse4.2"))) foo(int) { return 0; }
+int __attribute__((target("arch=sandybridge"))) foo(int);
+int __attribute__((target("arch=ivybridge"))) foo(int) {return 1;}
+int __attribute__((target("default"))) foo(int) { return 2; }
+
+struct S {
+int __attribute__((target("sse4.2"))) foo(int) { return 0; }
+int __attribute__((target("arch=sandybridge"))) foo(int);
+int __attribute__((target("arch=ivybridge"))) foo(int) {return 1;}
+int __attribute__((target("default"))) foo(int) { return 2; }
+};
+
+using FuncPtr = int (*)(int);
+using MemFuncPtr = int (S::*)(int);
+
+void f(FuncPtr, MemFuncPtr);
+
+int bar() {
+ FuncPtr Free = &foo;
+ MemFuncPtr Member = &S::foo;
+ S s;
+ f(foo, &S::foo);
+ return Free(1) + (s.*Member)(2);
+}
+
+// LINUX: @_Z3fooi.ifunc
+// LINUX: @_ZN1S3fooEi.ifunc
+
+// LINUX: define i32 @_Z3barv()
+// Store to Free of ifunc
+// LINUX: store i32 (i32)* @_Z3fooi.ifunc
+// Store to Member of ifunc
+// LINUX: store { i64, i64 } { i64 ptrtoint (i32 (%struct.S*, i32)* @_ZN1S3fooEi.ifunc to i64), i64 0 }, { i64, i64 }* [[MEMBER:%[a-z]+]]
+
+// Call to 'f' with the ifunc
+// LINUX: call void @_Z1fPFiiEM1SFiiE(i32 (i32)* @_Z3fooi.ifunc
+
+// WINDOWS: define dso_local i32 @"?bar@@YAHXZ"()
+// Store to Free
+// WINDOWS: store i32 (i32)* @"?foo@@[email protected]", i32 (i32)**
+// Store to Member
+// WINDOWS: store i8* bitcast (i32 (%struct.S*, i32)* @"?foo@S@@[email protected]" to i8*), i8**
+
+// Call to 'f'
+// WINDOWS: call void @"?f@@YAXP6AHH@ZP8S@@EAAHH@Z@Z"(i32 (i32)* @"?foo@@[email protected]", i8* bitcast (i32 (%struct.S*, i32)* @"?foo@S@@[email protected]" to i8*))
diff --git a/src/llvm-project/clang/test/CodeGenCXX/attr-target-mv-inalloca.cpp b/src/llvm-project/clang/test/CodeGenCXX/attr-target-mv-inalloca.cpp
new file mode 100644
index 0000000..0b65622
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/attr-target-mv-inalloca.cpp
@@ -0,0 +1,81 @@
+// RUN: %clang_cc1 -std=c++11 -triple i686-windows-msvc -emit-llvm %s -o - | FileCheck %s --check-prefix=WINDOWS
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows-msvc -emit-llvm %s -o - | FileCheck %s --check-prefix=WINDOWS64
+
+struct Foo {
+ Foo();
+ Foo(const Foo &o);
+ ~Foo();
+ int x;
+};
+int __attribute__((target("default"))) bar(Foo o) { return o.x; }
+int __attribute__((target("sse4.2"))) bar(Foo o) { return o.x + 1; }
+int __attribute__((target("arch=ivybridge"))) bar(Foo o) { return o.x + 2; }
+
+void usage() {
+ Foo f;
+ bar(f);
+}
+
+// WINDOWS: define dso_local i32 @"?bar@@YAHUFoo@@@Z"(<{ %struct.Foo }>* inalloca)
+// WINDOWS: %[[O:[0-9a-zA-Z]+]] = getelementptr inbounds <{ %struct.Foo }>, <{ %struct.Foo }>* %0, i32 0, i32 0
+// WINDOWS: %[[X:[0-9a-zA-Z]+]] = getelementptr inbounds %struct.Foo, %struct.Foo* %[[O]], i32 0, i32 0
+// WINDOWS: %[[LOAD:[0-9a-zA-Z]+]] = load i32, i32* %[[X]]
+// WINDOWS: ret i32 %[[LOAD]]
+
+// WINDOWS: define dso_local i32 @"?bar@@YAHUFoo@@@Z.sse4.2"(<{ %struct.Foo }>* inalloca)
+// WINDOWS: %[[O:[0-9a-zA-Z]+]] = getelementptr inbounds <{ %struct.Foo }>, <{ %struct.Foo }>* %0, i32 0, i32 0
+// WINDOWS: %[[X:[0-9a-zA-Z]+]] = getelementptr inbounds %struct.Foo, %struct.Foo* %[[O]], i32 0, i32 0
+// WINDOWS: %[[LOAD:[0-9a-zA-Z]+]] = load i32, i32* %[[X]]
+// WINDOWS: %[[ADD:[0-9a-zA-Z]+]] = add nsw i32 %[[LOAD]], 1
+// WINDOWS: ret i32 %[[ADD]]
+
+// WINDOWS: define dso_local i32 @"?bar@@YAHUFoo@@@Z.arch_ivybridge"(<{ %struct.Foo }>* inalloca)
+// WINDOWS: %[[O:[0-9a-zA-Z]+]] = getelementptr inbounds <{ %struct.Foo }>, <{ %struct.Foo }>* %0, i32 0, i32 0
+// WINDOWS: %[[X:[0-9a-zA-Z]+]] = getelementptr inbounds %struct.Foo, %struct.Foo* %[[O]], i32 0, i32 0
+// WINDOWS: %[[LOAD:[0-9a-zA-Z]+]] = load i32, i32* %[[X]]
+// WINDOWS: %[[ADD:[0-9a-zA-Z]+]] = add nsw i32 %[[LOAD]], 2
+// WINDOWS: ret i32 %[[ADD]]
+
+// WINDOWS: define dso_local void @"?usage@@YAXXZ"()
+// WINDOWS: %[[F:[0-9a-zA-Z]+]] = alloca %struct.Foo
+// WINDOWS: %[[ARGMEM:[0-9a-zA-Z]+]] = alloca inalloca <{ %struct.Foo }>
+// WINDOWS: %[[CALL:[0-9a-zA-Z]+]] = call i32 @"?bar@@YAHUFoo@@@Z.resolver"(<{ %struct.Foo }>* inalloca %[[ARGMEM]])
+
+// WINDOWS: define dso_local i32 @"?bar@@YAHUFoo@@@Z.resolver"(<{ %struct.Foo }>*)
+// WINDOWS: %[[RET:[0-9a-zA-Z]+]] = musttail call i32 @"?bar@@YAHUFoo@@@Z.arch_ivybridge"(<{ %struct.Foo }>* %0)
+// WINDOWS-NEXT: ret i32 %[[RET]]
+// WINDOWS: %[[RET:[0-9a-zA-Z]+]] = musttail call i32 @"?bar@@YAHUFoo@@@Z.sse4.2"(<{ %struct.Foo }>* %0)
+// WINDOWS-NEXT: ret i32 %[[RET]]
+// WINDOWS: %[[RET:[0-9a-zA-Z]+]] = musttail call i32 @"?bar@@YAHUFoo@@@Z"(<{ %struct.Foo }>* %0)
+// WINDOWS-NEXT: ret i32 %[[RET]]
+
+
+// WINDOWS64: define dso_local i32 @"?bar@@YAHUFoo@@@Z"(%struct.Foo* %[[O:[0-9a-zA-Z]+]])
+// WINDOWS64: %[[X:[0-9a-zA-Z]+]] = getelementptr inbounds %struct.Foo, %struct.Foo* %[[O]], i32 0, i32 0
+// WINDOWS64: %[[LOAD:[0-9a-zA-Z]+]] = load i32, i32* %[[X]]
+// WINDOWS64: ret i32 %[[LOAD]]
+
+// WINDOWS64: define dso_local i32 @"?bar@@YAHUFoo@@@Z.sse4.2"(%struct.Foo* %[[O:[0-9a-zA-Z]+]])
+// WINDOWS64: %[[X:[0-9a-zA-Z]+]] = getelementptr inbounds %struct.Foo, %struct.Foo* %[[O]], i32 0, i32 0
+// WINDOWS64: %[[LOAD:[0-9a-zA-Z]+]] = load i32, i32* %[[X]]
+// WINDOWS64: %[[ADD:[0-9a-zA-Z]+]] = add nsw i32 %[[LOAD]], 1
+// WINDOWS64: ret i32 %[[ADD]]
+
+// WINDOWS64: define dso_local i32 @"?bar@@YAHUFoo@@@Z.arch_ivybridge"(%struct.Foo* %[[O:[0-9a-zA-Z]+]])
+// WINDOWS64: %[[X:[0-9a-zA-Z]+]] = getelementptr inbounds %struct.Foo, %struct.Foo* %[[O]], i32 0, i32 0
+// WINDOWS64: %[[LOAD:[0-9a-zA-Z]+]] = load i32, i32* %[[X]]
+// WINDOWS64: %[[ADD:[0-9a-zA-Z]+]] = add nsw i32 %[[LOAD]], 2
+// WINDOWS64: ret i32 %[[ADD]]
+
+// WINDOWS64: define dso_local void @"?usage@@YAXXZ"()
+// WINDOWS64: %[[F:[0-9a-zA-Z]+]] = alloca %struct.Foo
+// WINDOWS64: %[[ARG:[0-9a-zA-Z.]+]] = alloca %struct.Foo
+// WINDOWS64: %[[CALL:[0-9a-zA-Z]+]] = call i32 @"?bar@@YAHUFoo@@@Z.resolver"(%struct.Foo* %[[ARG]])
+
+// WINDOWS64: define dso_local i32 @"?bar@@YAHUFoo@@@Z.resolver"(%struct.Foo*)
+// WINDOWS64: %[[RET:[0-9a-zA-Z]+]] = musttail call i32 @"?bar@@YAHUFoo@@@Z.arch_ivybridge"(%struct.Foo* %0)
+// WINDOWS64-NEXT: ret i32 %[[RET]]
+// WINDOWS64: %[[RET:[0-9a-zA-Z]+]] = musttail call i32 @"?bar@@YAHUFoo@@@Z.sse4.2"(%struct.Foo* %0)
+// WINDOWS64-NEXT: ret i32 %[[RET]]
+// WINDOWS64: %[[RET:[0-9a-zA-Z]+]] = musttail call i32 @"?bar@@YAHUFoo@@@Z"(%struct.Foo* %0)
+// WINDOWS64-NEXT: ret i32 %[[RET]]
diff --git a/src/llvm-project/clang/test/CodeGenCXX/attr-target-mv-member-funcs.cpp b/src/llvm-project/clang/test/CodeGenCXX/attr-target-mv-member-funcs.cpp
new file mode 100644
index 0000000..a63737e
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/attr-target-mv-member-funcs.cpp
@@ -0,0 +1,220 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix=LINUX
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows-pc -emit-llvm %s -o - | FileCheck %s --check-prefix=WINDOWS
+
+struct S {
+ int __attribute__((target("sse4.2"))) foo(int) { return 0; }
+ int __attribute__((target("arch=sandybridge"))) foo(int);
+ int __attribute__((target("arch=ivybridge"))) foo(int) { return 1; }
+ int __attribute__((target("default"))) foo(int) { return 2; }
+
+ S &__attribute__((target("arch=ivybridge"))) operator=(const S &) {
+ return *this;
+ }
+ S &__attribute__((target("default"))) operator=(const S &) {
+ return *this;
+ }
+};
+
+struct ConvertTo {
+ __attribute__((target("arch=ivybridge"))) operator S() const {
+ return S{};
+ }
+ __attribute__((target("default"))) operator S() const {
+ return S{};
+ }
+};
+
+int bar() {
+ S s;
+ S s2;
+ s2 = s;
+
+ ConvertTo C;
+ s2 = static_cast<S>(C);
+
+ return s.foo(0);
+}
+
+struct S2 {
+ int __attribute__((target("sse4.2"))) foo(int);
+ int __attribute__((target("arch=sandybridge"))) foo(int);
+ int __attribute__((target("arch=ivybridge"))) foo(int);
+ int __attribute__((target("default"))) foo(int);
+};
+
+int bar2() {
+ S2 s;
+ return s.foo(0);
+}
+
+int __attribute__((target("sse4.2"))) S2::foo(int) { return 0; }
+int __attribute__((target("arch=ivybridge"))) S2::foo(int) { return 1; }
+int __attribute__((target("default"))) S2::foo(int) { return 2; }
+
+template<typename T>
+struct templ {
+ int __attribute__((target("sse4.2"))) foo(int) { return 0; }
+ int __attribute__((target("arch=sandybridge"))) foo(int);
+ int __attribute__((target("arch=ivybridge"))) foo(int) { return 1; }
+ int __attribute__((target("default"))) foo(int) { return 2; }
+};
+
+int templ_use() {
+ templ<int> a;
+ templ<double> b;
+ return a.foo(1) + b.foo(2);
+}
+
+// LINUX: @_ZN1SaSERKS_.ifunc = ifunc %struct.S* (%struct.S*, %struct.S*), %struct.S* (%struct.S*, %struct.S*)* ()* @_ZN1SaSERKS_.resolver
+// LINUX: @_ZNK9ConvertTocv1SEv.ifunc = ifunc void (%struct.ConvertTo*), void (%struct.ConvertTo*)* ()* @_ZNK9ConvertTocv1SEv.resolver
+// LINUX: @_ZN1S3fooEi.ifunc = ifunc i32 (%struct.S*, i32), i32 (%struct.S*, i32)* ()* @_ZN1S3fooEi.resolver
+// LINUX: @_ZN2S23fooEi.ifunc = ifunc i32 (%struct.S2*, i32), i32 (%struct.S2*, i32)* ()* @_ZN2S23fooEi.resolver
+// Templates:
+// LINUX: @_ZN5templIiE3fooEi.ifunc = ifunc i32 (%struct.templ*, i32), i32 (%struct.templ*, i32)* ()* @_ZN5templIiE3fooEi.resolver
+// LINUX: @_ZN5templIdE3fooEi.ifunc = ifunc i32 (%struct.templ.0*, i32), i32 (%struct.templ.0*, i32)* ()* @_ZN5templIdE3fooEi.resolver
+
+// LINUX: define i32 @_Z3barv()
+// LINUX: %s = alloca %struct.S, align 1
+// LINUX: %s2 = alloca %struct.S, align 1
+// LINUX: %C = alloca %struct.ConvertTo, align 1
+// LINUX: call dereferenceable(1) %struct.S* @_ZN1SaSERKS_.ifunc(%struct.S* %s2
+// LINUX: call void @_ZNK9ConvertTocv1SEv.ifunc(%struct.ConvertTo* %C)
+// LINUX: call dereferenceable(1) %struct.S* @_ZN1SaSERKS_.ifunc(%struct.S* %s2
+// LINUX: call i32 @_ZN1S3fooEi.ifunc(%struct.S* %s, i32 0)
+
+// WINDOWS: define dso_local i32 @"?bar@@YAHXZ"()
+// WINDOWS: %s = alloca %struct.S, align 1
+// WINDOWS: %s2 = alloca %struct.S, align 1
+// WINDOWS: %C = alloca %struct.ConvertTo, align 1
+// WINDOWS: call dereferenceable(1) %struct.S* @"??4S@@QEAAAEAU0@AEBU0@@Z.resolver"(%struct.S* %s2
+// WINDOWS: call void @"??BConvertTo@@QEBA?AUS@@XZ.resolver"(%struct.ConvertTo* %C
+// WINDOWS: call dereferenceable(1) %struct.S* @"??4S@@QEAAAEAU0@AEBU0@@Z.resolver"(%struct.S* %s2
+// WINDOWS: call i32 @"?foo@S@@[email protected]"(%struct.S* %s, i32 0)
+
+// LINUX: define %struct.S* (%struct.S*, %struct.S*)* @_ZN1SaSERKS_.resolver() comdat
+// LINUX: ret %struct.S* (%struct.S*, %struct.S*)* @_ZN1SaSERKS_.arch_ivybridge
+// LINUX: ret %struct.S* (%struct.S*, %struct.S*)* @_ZN1SaSERKS_
+
+// WINDOWS: define dso_local %struct.S* @"??4S@@QEAAAEAU0@AEBU0@@Z.resolver"(%struct.S*, %struct.S*)
+// WINDOWS: call %struct.S* @"??4S@@QEAAAEAU0@AEBU0@@Z.arch_ivybridge"
+// WINDOWS: call %struct.S* @"??4S@@QEAAAEAU0@AEBU0@@Z"
+
+// LINUX: define void (%struct.ConvertTo*)* @_ZNK9ConvertTocv1SEv.resolver() comdat
+// LINUX: ret void (%struct.ConvertTo*)* @_ZNK9ConvertTocv1SEv.arch_ivybridge
+// LINUX: ret void (%struct.ConvertTo*)* @_ZNK9ConvertTocv1SEv
+
+// WINDOWS: define dso_local void @"??BConvertTo@@QEBA?AUS@@XZ.resolver"(%struct.ConvertTo*, %struct.S*)
+// WINDOWS: call void @"??BConvertTo@@QEBA?AUS@@XZ.arch_ivybridge"
+// WINDOWS: call void @"??BConvertTo@@QEBA?AUS@@XZ"
+
+// LINUX: define i32 (%struct.S*, i32)* @_ZN1S3fooEi.resolver() comdat
+// LINUX: ret i32 (%struct.S*, i32)* @_ZN1S3fooEi.arch_sandybridge
+// LINUX: ret i32 (%struct.S*, i32)* @_ZN1S3fooEi.arch_ivybridge
+// LINUX: ret i32 (%struct.S*, i32)* @_ZN1S3fooEi.sse4.2
+// LINUX: ret i32 (%struct.S*, i32)* @_ZN1S3fooEi
+
+// WINDOWS: define dso_local i32 @"?foo@S@@[email protected]"(%struct.S*, i32)
+// WINDOWS: call i32 @"?foo@S@@[email protected]_sandybridge"
+// WINDOWS: call i32 @"?foo@S@@[email protected]_ivybridge"
+// WINDOWS: call i32 @"?foo@S@@[email protected]"
+// WINDOWS: call i32 @"?foo@S@@QEAAHH@Z"
+
+// LINUX: define i32 @_Z4bar2v()
+// LINUX: call i32 @_ZN2S23fooEi.ifunc
+
+// WINDOWS: define dso_local i32 @"?bar2@@YAHXZ"()
+// WINDOWS: call i32 @"?foo@S2@@[email protected]"
+
+// LINUX: define i32 (%struct.S2*, i32)* @_ZN2S23fooEi.resolver() comdat
+// LINUX: ret i32 (%struct.S2*, i32)* @_ZN2S23fooEi.arch_sandybridge
+// LINUX: ret i32 (%struct.S2*, i32)* @_ZN2S23fooEi.arch_ivybridge
+// LINUX: ret i32 (%struct.S2*, i32)* @_ZN2S23fooEi.sse4.2
+// LINUX: ret i32 (%struct.S2*, i32)* @_ZN2S23fooEi
+
+// WINDOWS: define dso_local i32 @"?foo@S2@@[email protected]"(%struct.S2*, i32)
+// WINDOWS: call i32 @"?foo@S2@@[email protected]_sandybridge"
+// WINDOWS: call i32 @"?foo@S2@@[email protected]_ivybridge"
+// WINDOWS: call i32 @"?foo@S2@@[email protected]"
+// WINDOWS: call i32 @"?foo@S2@@QEAAHH@Z"
+
+// LINUX: define i32 @_ZN2S23fooEi.sse4.2(%struct.S2* %this, i32)
+// LINUX: define i32 @_ZN2S23fooEi.arch_ivybridge(%struct.S2* %this, i32)
+// LINUX: define i32 @_ZN2S23fooEi(%struct.S2* %this, i32)
+
+// WINDOWS: define dso_local i32 @"?foo@S2@@[email protected]"(%struct.S2* %this, i32)
+// WINDOWS: define dso_local i32 @"?foo@S2@@[email protected]_ivybridge"(%struct.S2* %this, i32)
+// WINDOWS: define dso_local i32 @"?foo@S2@@QEAAHH@Z"(%struct.S2* %this, i32)
+
+// LINUX: define i32 @_Z9templ_usev()
+// LINUX: call i32 @_ZN5templIiE3fooEi.ifunc
+// LINUX: call i32 @_ZN5templIdE3fooEi.ifunc
+
+// WINDOWS: define dso_local i32 @"?templ_use@@YAHXZ"()
+// WINDOWS: call i32 @"?foo@?$templ@H@@[email protected]"
+// WINDOWS: call i32 @"?foo@?$templ@N@@[email protected]"
+
+// LINUX: define i32 (%struct.templ*, i32)* @_ZN5templIiE3fooEi.resolver() comdat
+// LINUX: ret i32 (%struct.templ*, i32)* @_ZN5templIiE3fooEi.arch_sandybridge
+// LINUX: ret i32 (%struct.templ*, i32)* @_ZN5templIiE3fooEi.arch_ivybridge
+// LINUX: ret i32 (%struct.templ*, i32)* @_ZN5templIiE3fooEi.sse4.2
+// LINUX: ret i32 (%struct.templ*, i32)* @_ZN5templIiE3fooEi
+
+// WINDOWS: define dso_local i32 @"?foo@?$templ@H@@[email protected]"(%struct.templ*, i32)
+// WINDOWS: call i32 @"?foo@?$templ@H@@[email protected]_sandybridge"
+// WINDOWS: call i32 @"?foo@?$templ@H@@[email protected]_ivybridge"
+// WINDOWS: call i32 @"?foo@?$templ@H@@[email protected]"
+// WINDOWS: call i32 @"?foo@?$templ@H@@QEAAHH@Z"
+
+// LINUX: define i32 (%struct.templ.0*, i32)* @_ZN5templIdE3fooEi.resolver() comdat
+// LINUX: ret i32 (%struct.templ.0*, i32)* @_ZN5templIdE3fooEi.arch_sandybridge
+// LINUX: ret i32 (%struct.templ.0*, i32)* @_ZN5templIdE3fooEi.arch_ivybridge
+// LINUX: ret i32 (%struct.templ.0*, i32)* @_ZN5templIdE3fooEi.sse4.2
+// LINUX: ret i32 (%struct.templ.0*, i32)* @_ZN5templIdE3fooEi
+
+// WINDOWS: define dso_local i32 @"?foo@?$templ@N@@[email protected]"(%struct.templ.0*, i32) comdat
+// WINDOWS: call i32 @"?foo@?$templ@N@@[email protected]_sandybridge"
+// WINDOWS: call i32 @"?foo@?$templ@N@@[email protected]_ivybridge"
+// WINDOWS: call i32 @"?foo@?$templ@N@@[email protected]"
+// WINDOWS: call i32 @"?foo@?$templ@N@@QEAAHH@Z"
+
+// LINUX: define linkonce_odr i32 @_ZN1S3fooEi.sse4.2(%struct.S* %this, i32)
+// LINUX: ret i32 0
+
+// WINDOWS: define linkonce_odr dso_local i32 @"?foo@S@@[email protected]"(%struct.S* %this, i32)
+// WINDOWS: ret i32 0
+
+// LINUX: declare i32 @_ZN1S3fooEi.arch_sandybridge(%struct.S*, i32)
+
+// WINDOWS: declare dso_local i32 @"?foo@S@@[email protected]_sandybridge"(%struct.S*, i32)
+
+// LINUX: define linkonce_odr i32 @_ZN1S3fooEi.arch_ivybridge(%struct.S* %this, i32)
+// LINUX: ret i32 1
+
+// WINDOWS: define linkonce_odr dso_local i32 @"?foo@S@@[email protected]_ivybridge"(%struct.S* %this, i32)
+// WINDOWS: ret i32 1
+
+// LINUX: define linkonce_odr i32 @_ZN1S3fooEi(%struct.S* %this, i32)
+// LINUX: ret i32 2
+
+// WINDOWS: define linkonce_odr dso_local i32 @"?foo@S@@QEAAHH@Z"(%struct.S* %this, i32)
+// WINDOWS: ret i32 2
+
+// LINUX: define linkonce_odr i32 @_ZN5templIiE3fooEi.sse4.2
+// LINUX: declare i32 @_ZN5templIiE3fooEi.arch_sandybridge
+// LINUX: define linkonce_odr i32 @_ZN5templIiE3fooEi.arch_ivybridge
+// LINUX: define linkonce_odr i32 @_ZN5templIiE3fooEi
+
+// WINDOWS: define linkonce_odr dso_local i32 @"?foo@?$templ@H@@[email protected]"
+// WINDOWS: declare dso_local i32 @"?foo@?$templ@H@@[email protected]_sandybridge"
+// WINDOWS: define linkonce_odr dso_local i32 @"?foo@?$templ@H@@[email protected]_ivybridge"
+// WINDOWS: define linkonce_odr dso_local i32 @"?foo@?$templ@H@@QEAAHH@Z"
+
+// LINUX: define linkonce_odr i32 @_ZN5templIdE3fooEi.sse4.2
+// LINUX: declare i32 @_ZN5templIdE3fooEi.arch_sandybridge
+// LINUX: define linkonce_odr i32 @_ZN5templIdE3fooEi.arch_ivybridge
+// LINUX: define linkonce_odr i32 @_ZN5templIdE3fooEi
+
+// WINDOWS: define linkonce_odr dso_local i32 @"?foo@?$templ@N@@[email protected]"
+// WINDOWS: declare dso_local i32 @"?foo@?$templ@N@@[email protected]_sandybridge"
+// WINDOWS: define linkonce_odr dso_local i32 @"?foo@?$templ@N@@[email protected]_ivybridge"
+// WINDOWS: define linkonce_odr dso_local i32 @"?foo@?$templ@N@@QEAAHH@Z"
diff --git a/src/llvm-project/clang/test/CodeGenCXX/attr-target-mv-modules.cpp b/src/llvm-project/clang/test/CodeGenCXX/attr-target-mv-modules.cpp
new file mode 100644
index 0000000..6ff2046
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/attr-target-mv-modules.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -fmodules -emit-llvm %s -o - | FileCheck %s
+#pragma clang module build A
+module A {}
+#pragma clang module contents
+#pragma clang module begin A
+__attribute__((target("default"))) void f();
+__attribute__((target("sse4.2"))) void f();
+#pragma clang module end
+#pragma clang module endbuild
+
+#pragma clang module build B
+module B {}
+#pragma clang module contents
+#pragma clang module begin B
+__attribute__((target("default"))) void f();
+__attribute__((target("sse4.2"))) void f();
+#pragma clang module end
+#pragma clang module endbuild
+
+#pragma clang module import A
+#pragma clang module import B
+void g() { f(); }
+
+// Negative tests to validate that the resolver only calls each 1x.
+// CHECK: define void ()* @_Z1fv.resolver
+// CHECK: ret void ()* @_Z1fv.sse4.2
+// CHECK-NOT: ret void ()* @_Z1fv.sse4.2
+// CHECK: ret void ()* @_Z1fv
+// CHECK-NOT: ret void ()* @_Z1fv
diff --git a/src/llvm-project/clang/test/CodeGenCXX/attr-target-mv-out-of-line-defs.cpp b/src/llvm-project/clang/test/CodeGenCXX/attr-target-mv-out-of-line-defs.cpp
new file mode 100644
index 0000000..1c051b3
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/attr-target-mv-out-of-line-defs.cpp
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix=LINUX
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows-pc -emit-llvm %s -o - | FileCheck %s --check-prefix=WINDOWS
+struct S {
+ int __attribute__((target("sse4.2"))) foo(int);
+ int __attribute__((target("arch=sandybridge"))) foo(int);
+ int __attribute__((target("arch=ivybridge"))) foo(int);
+ int __attribute__((target("default"))) foo(int);
+};
+
+int __attribute__((target("default"))) S::foo(int) { return 2; }
+int __attribute__((target("sse4.2"))) S::foo(int) { return 0; }
+int __attribute__((target("arch=ivybridge"))) S::foo(int) { return 1; }
+
+int bar() {
+ S s;
+ return s.foo(0);
+}
+
+// LINUX: @_ZN1S3fooEi.ifunc = ifunc i32 (%struct.S*, i32), i32 (%struct.S*, i32)* ()* @_ZN1S3fooEi.resolver
+
+// LINUX: define i32 @_ZN1S3fooEi(%struct.S* %this, i32)
+// LINUX: ret i32 2
+
+// WINDOWS: define dso_local i32 @"?foo@S@@QEAAHH@Z"(%struct.S* %this, i32)
+// WINDOWS: ret i32 2
+
+// LINUX: define i32 @_ZN1S3fooEi.sse4.2(%struct.S* %this, i32)
+// LINUX: ret i32 0
+
+// WINDOWS: define dso_local i32 @"?foo@S@@[email protected]"(%struct.S* %this, i32)
+// WINDOWS: ret i32 0
+
+// LINUX: define i32 @_ZN1S3fooEi.arch_ivybridge(%struct.S* %this, i32)
+// LINUX: ret i32 1
+
+// WINDOWS: define dso_local i32 @"?foo@S@@[email protected]_ivybridge"(%struct.S* %this, i32)
+// WINDOWS: ret i32 1
+
+// LINUX: define i32 @_Z3barv()
+// LINUX: %s = alloca %struct.S, align 1
+// LINUX: %call = call i32 @_ZN1S3fooEi.ifunc(%struct.S* %s, i32 0)
+
+// WINDOWS: define dso_local i32 @"?bar@@YAHXZ"()
+// WINDOWS: %s = alloca %struct.S, align 1
+// WINDOWS: %call = call i32 @"?foo@S@@[email protected]"(%struct.S* %s, i32 0)
+
+// LINUX: define i32 (%struct.S*, i32)* @_ZN1S3fooEi.resolver() comdat
+// LINUX: ret i32 (%struct.S*, i32)* @_ZN1S3fooEi.arch_sandybridge
+// LINUX: ret i32 (%struct.S*, i32)* @_ZN1S3fooEi.arch_ivybridge
+// LINUX: ret i32 (%struct.S*, i32)* @_ZN1S3fooEi.sse4.2
+// LINUX: ret i32 (%struct.S*, i32)* @_ZN1S3fooEi
+
+// WINDOWS: define dso_local i32 @"?foo@S@@[email protected]"(%struct.S*, i32) comdat
+// WINDOWS: call i32 @"?foo@S@@[email protected]_sandybridge"(%struct.S* %0, i32 %1)
+// WINDOWS: call i32 @"?foo@S@@[email protected]_ivybridge"(%struct.S* %0, i32 %1)
+// WINDOWS: call i32 @"?foo@S@@[email protected]"(%struct.S* %0, i32 %1)
+// WINDOWS: call i32 @"?foo@S@@QEAAHH@Z"(%struct.S* %0, i32 %1)
+
+// LINUX: declare i32 @_ZN1S3fooEi.arch_sandybridge(%struct.S*, i32)
+
+// WINDOWS: declare dso_local i32 @"?foo@S@@[email protected]_sandybridge"(%struct.S*, i32)
diff --git a/src/llvm-project/clang/test/CodeGenCXX/attr-target-mv-overloads.cpp b/src/llvm-project/clang/test/CodeGenCXX/attr-target-mv-overloads.cpp
new file mode 100644
index 0000000..a213d24
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/attr-target-mv-overloads.cpp
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix=LINUX
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows-pc -emit-llvm %s -o - | FileCheck %s --check-prefix=WINDOWS
+
+int __attribute__((target("sse4.2"))) foo_overload(int) { return 0; }
+int __attribute__((target("arch=sandybridge"))) foo_overload(int);
+int __attribute__((target("arch=ivybridge"))) foo_overload(int) {return 1;}
+int __attribute__((target("default"))) foo_overload(int) { return 2; }
+int __attribute__((target("sse4.2"))) foo_overload(void) { return 0; }
+int __attribute__((target("arch=sandybridge"))) foo_overload(void);
+int __attribute__((target("arch=ivybridge"))) foo_overload(void) {return 1;}
+int __attribute__((target("default"))) foo_overload(void) { return 2; }
+
+int bar2() {
+ return foo_overload() + foo_overload(1);
+}
+
+// LINUX: @_Z12foo_overloadv.ifunc = ifunc i32 (), i32 ()* ()* @_Z12foo_overloadv.resolver
+// LINUX: @_Z12foo_overloadi.ifunc = ifunc i32 (i32), i32 (i32)* ()* @_Z12foo_overloadi.resolver
+
+// LINUX: define i32 @_Z12foo_overloadi.sse4.2(i32)
+// LINUX: ret i32 0
+// LINUX: define i32 @_Z12foo_overloadi.arch_ivybridge(i32)
+// LINUX: ret i32 1
+// LINUX: define i32 @_Z12foo_overloadi(i32)
+// LINUX: ret i32 2
+// LINUX: define i32 @_Z12foo_overloadv.sse4.2()
+// LINUX: ret i32 0
+// LINUX: define i32 @_Z12foo_overloadv.arch_ivybridge()
+// LINUX: ret i32 1
+// LINUX: define i32 @_Z12foo_overloadv()
+// LINUX: ret i32 2
+
+// WINDOWS: define dso_local i32 @"?foo_overload@@[email protected]"(i32)
+// WINDOWS: ret i32 0
+// WINDOWS: define dso_local i32 @"?foo_overload@@[email protected]_ivybridge"(i32)
+// WINDOWS: ret i32 1
+// WINDOWS: define dso_local i32 @"?foo_overload@@YAHH@Z"(i32)
+// WINDOWS: ret i32 2
+// WINDOWS: define dso_local i32 @"?foo_overload@@YAHXZ.sse4.2"()
+// WINDOWS: ret i32 0
+// WINDOWS: define dso_local i32 @"?foo_overload@@YAHXZ.arch_ivybridge"()
+// WINDOWS: ret i32 1
+// WINDOWS: define dso_local i32 @"?foo_overload@@YAHXZ"()
+// WINDOWS: ret i32 2
+
+// LINUX: define i32 @_Z4bar2v()
+// LINUX: call i32 @_Z12foo_overloadv.ifunc()
+// LINUX: call i32 @_Z12foo_overloadi.ifunc(i32 1)
+
+// WINDOWS: define dso_local i32 @"?bar2@@YAHXZ"()
+// WINDOWS: call i32 @"?foo_overload@@YAHXZ.resolver"()
+// WINDOWS: call i32 @"?foo_overload@@[email protected]"(i32 1)
+
+// LINUX: define i32 ()* @_Z12foo_overloadv.resolver() comdat
+// LINUX: ret i32 ()* @_Z12foo_overloadv.arch_sandybridge
+// LINUX: ret i32 ()* @_Z12foo_overloadv.arch_ivybridge
+// LINUX: ret i32 ()* @_Z12foo_overloadv.sse4.2
+// LINUX: ret i32 ()* @_Z12foo_overloadv
+
+// WINDOWS: define dso_local i32 @"?foo_overload@@YAHXZ.resolver"() comdat
+// WINDOWS: call i32 @"?foo_overload@@YAHXZ.arch_sandybridge"
+// WINDOWS: call i32 @"?foo_overload@@YAHXZ.arch_ivybridge"
+// WINDOWS: call i32 @"?foo_overload@@YAHXZ.sse4.2"
+// WINDOWS: call i32 @"?foo_overload@@YAHXZ"
+
+// LINUX: define i32 (i32)* @_Z12foo_overloadi.resolver() comdat
+// LINUX: ret i32 (i32)* @_Z12foo_overloadi.arch_sandybridge
+// LINUX: ret i32 (i32)* @_Z12foo_overloadi.arch_ivybridge
+// LINUX: ret i32 (i32)* @_Z12foo_overloadi.sse4.2
+// LINUX: ret i32 (i32)* @_Z12foo_overloadi
+
+// WINDOWS: define dso_local i32 @"?foo_overload@@[email protected]"(i32) comdat
+// WINDOWS: call i32 @"?foo_overload@@[email protected]_sandybridge"
+// WINDOWS: call i32 @"?foo_overload@@[email protected]_ivybridge"
+// WINDOWS: call i32 @"?foo_overload@@[email protected]"
+// WINDOWS: call i32 @"?foo_overload@@YAHH@Z"
+
+// LINUX: declare i32 @_Z12foo_overloadv.arch_sandybridge()
+// LINUX: declare i32 @_Z12foo_overloadi.arch_sandybridge(i32)
+
+// WINDOWS: declare dso_local i32 @"?foo_overload@@YAHXZ.arch_sandybridge"()
+// WINDOWS: declare dso_local i32 @"?foo_overload@@[email protected]_sandybridge"(i32)
diff --git a/src/llvm-project/clang/test/CodeGenCXX/attr-used.cpp b/src/llvm-project/clang/test/CodeGenCXX/attr-used.cpp
new file mode 100644
index 0000000..d2a73f7
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/attr-used.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -o - %s | FileCheck %s
+
+// <rdar://problem/8684363>: clang++ not respecting __attribute__((used)) on destructors
+struct X0 {
+ // CHECK-DAG: define linkonce_odr {{.*}} @_ZN2X0C1Ev
+ __attribute__((used)) X0() {}
+ // CHECK-DAG: define linkonce_odr {{.*}} @_ZN2X0D1Ev
+ __attribute__((used)) ~X0() {}
+};
+
+// PR19743: not emitting __attribute__((used)) inline methods in nested classes.
+struct X1 {
+ struct Nested {
+ // CHECK-DAG: define linkonce_odr {{.*}} @_ZN2X16Nested1fEv
+ void __attribute__((used)) f() {}
+ };
+};
+
+struct X2 {
+ // We must delay emission of bar() until foo() has had its body parsed,
+ // otherwise foo() would not be emitted.
+ void __attribute__((used)) bar() { foo(); }
+ void foo() { }
+
+ // CHECK-DAG: define linkonce_odr {{.*}} @_ZN2X23barEv
+ // CHECK-DAG: define linkonce_odr {{.*}} @_ZN2X23fooEv
+};
diff --git a/src/llvm-project/clang/test/CodeGenCXX/attr-x86-interrupt.cpp b/src/llvm-project/clang/test/CodeGenCXX/attr-x86-interrupt.cpp
new file mode 100644
index 0000000..30cf58b
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/attr-x86-interrupt.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu %s -emit-llvm -o - | FileCheck %s --check-prefix=X86_64_LINUX
+// RUN: %clang_cc1 -triple i386-unknown-linux-gnu %s -emit-llvm -o - | FileCheck %s --check-prefix=X86_LINUX
+// RUN: %clang_cc1 -triple x86_64-pc-win32 %s -emit-llvm -o - | FileCheck %s --check-prefix=X86_64_WIN
+// RUN: %clang_cc1 -triple i386-pc-win32 %s -emit-llvm -o - | FileCheck %s --check-prefix=X86_WIN
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnux32 %s -emit-llvm -o - | FileCheck %s --check-prefix=X86_64_LINUX
+
+#ifdef __x86_64__
+typedef __UINT64_TYPE__ uword;
+#else
+typedef __UINT32_TYPE__ uword;
+#endif
+
+__attribute__((interrupt)) void foo7(int *a, uword b) {}
+namespace S {
+__attribute__((interrupt)) void foo8(int *a) {}
+}
+struct St {
+static void foo9(int *a) __attribute__((interrupt)) {}
+};
+// X86_64_LINUX: @llvm.used = appending global [3 x i8*] [i8* bitcast (void (i32*, i64)* @{{.*}}foo7{{.*}} to i8*), i8* bitcast (void (i32*)* @{{.*}}foo8{{.*}} to i8*), i8* bitcast (void (i32*)* @{{.*}}foo9{{.*}} to i8*)], section "llvm.metadata"
+// X86_64_LINUX: define x86_intrcc void @{{.*}}foo7{{.*}}(i32* %{{.+}}, i64 %{{.+}})
+// X86_64_LINUX: define x86_intrcc void @{{.*}}foo8{{.*}}(i32* %{{.+}})
+// X86_64_LINUX: define linkonce_odr x86_intrcc void @{{.*}}foo9{{.*}}(i32* %{{.+}})
+// X86_LINUX: @llvm.used = appending global [3 x i8*] [i8* bitcast (void (i32*, i32)* @{{.*}}foo7{{.*}} to i8*), i8* bitcast (void (i32*)* @{{.*}}foo8{{.*}} to i8*), i8* bitcast (void (i32*)* @{{.*}}foo9{{.*}} to i8*)], section "llvm.metadata"
+// X86_LINUX: define x86_intrcc void @{{.*}}foo7{{.*}}(i32* %{{.+}}, i32 %{{.+}})
+// X86_LINUX: define x86_intrcc void @{{.*}}foo8{{.*}}(i32* %{{.+}})
+// X86_LINUX: define linkonce_odr x86_intrcc void @{{.*}}foo9{{.*}}(i32* %{{.+}})
+// X86_64_WIN: @llvm.used = appending global [3 x i8*] [i8* bitcast (void (i32*, i64)* @{{.*}}foo7{{.*}} to i8*), i8* bitcast (void (i32*)* @{{.*}}foo8{{.*}} to i8*), i8* bitcast (void (i32*)* @{{.*}}foo9{{.*}} to i8*)], section "llvm.metadata"
+// X86_64_WIN: define dso_local x86_intrcc void @{{.*}}foo7{{.*}}(i32* %{{.+}}, i64 %{{.+}})
+// X86_64_WIN: define dso_local x86_intrcc void @{{.*}}foo8{{.*}}(i32* %{{.+}})
+// X86_64_WIN: define linkonce_odr dso_local x86_intrcc void @{{.*}}foo9{{.*}}(i32* %{{.+}})
+// X86_WIN: @llvm.used = appending global [3 x i8*] [i8* bitcast (void (i32*, i32)* @{{.*}}foo7{{.*}} to i8*), i8* bitcast (void (i32*)* @{{.*}}foo8{{.*}} to i8*), i8* bitcast (void (i32*)* @{{.*}}foo9{{.*}} to i8*)], section "llvm.metadata"
+// X86_WIN: define dso_local x86_intrcc void @{{.*}}foo7{{.*}}(i32* %{{.+}}, i32 %{{.+}})
+// X86_WIN: define dso_local x86_intrcc void @{{.*}}foo8{{.*}}(i32* %{{.+}})
+// X86_WIN: define linkonce_odr dso_local x86_intrcc void @{{.*}}foo9{{.*}}(i32* %{{.+}})
diff --git a/src/llvm-project/clang/test/CodeGenCXX/attr-x86-no_caller_saved_registers.cpp b/src/llvm-project/clang/test/CodeGenCXX/attr-x86-no_caller_saved_registers.cpp
new file mode 100644
index 0000000..c032e38
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/attr-x86-no_caller_saved_registers.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-pc-win32 %s -emit-llvm -o - | FileCheck %s
+
+// CHECK: foo{{[^#]*}}#[[ATTRS:[0-9]+]]
+__attribute__((no_caller_saved_registers)) void foo() {}
+namespace S {
+// CHECK: bar{{[^#]*}}#[[ATTRS]]
+__attribute__((no_caller_saved_registers)) void bar(int *a) { foo(); }
+}
+
+struct St {
+ static void baz(int *a) __attribute__((no_caller_saved_registers)) { S::bar(a); }
+};
+
+__attribute((no_caller_saved_registers)) void (*foobar)(void);
+
+// CHECK-LABEL: @main
+int main(int argc, char **argv) {
+ St::baz(&argc);
+ // CHECK: [[FOOBAR:%.+]] = load void ()*, void ()** @{{.*}}foobar{{.*}},
+ // CHECK-NEXT: call void [[FOOBAR]]() #[[ATTRS1:.+]]
+ foobar();
+ return 0;
+}
+
+// CHECK: baz{{[^#]*}}#[[ATTRS]]
+
+// CHECK: attributes #[[ATTRS]] = {
+// CHECK-SAME: "no_caller_saved_registers"
+// CHECK-SAME: }
+// CHECK: attributes #[[ATTRS1]] = { "no_caller_saved_registers" }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/attr.cpp b/src/llvm-project/clang/test/CodeGenCXX/attr.cpp
new file mode 100644
index 0000000..7f5595f
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/attr.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: @test2 = alias i32 (), i32 ()* @_Z5test1v
+
+// CHECK: define i32 @_Z3foov() [[NUW:#[0-9]+]] align 1024
+int foo() __attribute__((aligned(1024)));
+int foo() { }
+
+class C {
+ virtual void bar1() __attribute__((aligned(1)));
+ virtual void bar2() __attribute__((aligned(2)));
+ virtual void bar3() __attribute__((aligned(1024)));
+ void bar4() __attribute__((aligned(1024)));
+} c;
+
+// CHECK: define void @_ZN1C4bar1Ev(%class.C* %this) unnamed_addr [[NUW]] align 2
+void C::bar1() { }
+
+// CHECK: define void @_ZN1C4bar2Ev(%class.C* %this) unnamed_addr [[NUW]] align 2
+void C::bar2() { }
+
+// CHECK: define void @_ZN1C4bar3Ev(%class.C* %this) unnamed_addr [[NUW]] align 1024
+void C::bar3() { }
+
+// CHECK: define void @_ZN1C4bar4Ev(%class.C* %this) [[NUW]] align 1024
+void C::bar4() { }
+
+// PR6635
+// CHECK-LABEL: define i32 @_Z5test1v()
+int test1() { return 10; }
+// CHECK at top of file
+extern "C" int test2() __attribute__((alias("_Z5test1v")));
+
+// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/attribute_internal_linkage.cpp b/src/llvm-project/clang/test/CodeGenCXX/attribute_internal_linkage.cpp
new file mode 100644
index 0000000..21cd44e
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/attribute_internal_linkage.cpp
@@ -0,0 +1,79 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -std=c++11 -emit-llvm -o - %s | FileCheck %s
+
+__attribute__((internal_linkage)) void f() {}
+// CHECK-DAG: define internal void @_ZL1fv
+
+class A {
+public:
+ static int y __attribute__((internal_linkage));
+ static int y2 [[clang::internal_linkage]];
+// CHECK-DAG: @_ZN1A1yE = internal global
+// CHECK-DAG: @_ZN1A2y2E = internal global
+ void f1() __attribute__((internal_linkage));
+// CHECK-DAG: define internal void @_ZN1A2f1Ev
+ void f2() __attribute__((internal_linkage)) {}
+// CHECK-DAG: define internal void @_ZN1A2f2Ev
+ static void f4() __attribute__((internal_linkage)) {}
+// CHECK-DAG: define internal void @_ZN1A2f4Ev
+ A() __attribute__((internal_linkage)) {}
+// CHECK-DAG: define internal void @_ZN1AC1Ev
+// CHECK-DAG: define internal void @_ZN1AC2Ev
+ ~A() __attribute__((internal_linkage)) {}
+// CHECK-DAG: define internal void @_ZN1AD1Ev
+// CHECK-DAG: define internal void @_ZN1AD2Ev
+};
+
+int A::y;
+int A::y2;
+
+void A::f1() {
+}
+
+// Forward declaration w/o an attribute.
+class B;
+
+// Internal_linkage on a class affects all its members.
+class __attribute__((internal_linkage)) B {
+public:
+ B() {}
+ // CHECK-DAG: define internal void @_ZNL1BC1Ev
+ // CHECK-DAG: define internal void @_ZNL1BC2Ev
+ ~B() {}
+ // CHECK-DAG: define internal void @_ZNL1BD1Ev
+ // CHECK-DAG: define internal void @_ZNL1BD2Ev
+ void f() {};
+ // CHECK-DAG: define internal void @_ZNL1B1fEv
+ static int x;
+ // CHECK-DAG: @_ZNL1B1xE = internal global
+};
+
+int B::x;
+
+// Forward declaration with the attribute.
+class __attribute__((internal_linkage)) C;
+class C {
+public:
+ static int x;
+ // CHECK-DAG: @_ZNL1C1xE = internal global
+};
+
+int C::x;
+
+__attribute__((internal_linkage)) void g();
+void g() {}
+// CHECK-DAG: define internal void @_ZL1gv()
+
+void use() {
+ A a;
+ a.f1();
+ a.f2();
+ A::f4();
+ f();
+ int &Y = A::y;
+ int &Y2 = A::y2;
+ B b;
+ b.f();
+ int &XX2 = B::x;
+ g();
+ int &XX3 = C::x;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/auto-var-init.cpp b/src/llvm-project/clang/test/CodeGenCXX/auto-var-init.cpp
new file mode 100644
index 0000000..0d13c0a
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/auto-var-init.cpp
@@ -0,0 +1,1350 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fblocks %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fblocks -ftrivial-auto-var-init=pattern %s -emit-llvm -o - | FileCheck %s -check-prefix=PATTERN
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fblocks -ftrivial-auto-var-init=zero %s -emit-llvm -o - | FileCheck %s -check-prefix=ZERO
+
+template<typename T> void used(T &) noexcept;
+
+#define TEST_UNINIT(NAME, TYPE) \
+ using type_##NAME = TYPE; \
+ void test_##NAME##_uninit() { \
+ type_##NAME uninit; \
+ used(uninit); \
+ }
+
+// Value initialization on scalars, aggregate initialization on aggregates.
+#define TEST_BRACES(NAME, TYPE) \
+ using type_##NAME = TYPE; \
+ void test_##NAME##_braces() { \
+ type_##NAME braces = {}; \
+ used(braces); \
+ }
+
+#define TEST_CUSTOM(NAME, TYPE, ...) \
+ using type_##NAME = TYPE; \
+ void test_##NAME##_custom() { \
+ type_##NAME custom __VA_ARGS__; \
+ used(custom); \
+ }
+
+// None of the synthesized globals should contain `undef`.
+// PATTERN-NOT: undef
+// ZERO-NOT: undef
+
+// PATTERN: @__const.test_empty_uninit.uninit = private unnamed_addr constant %struct.empty { i8 -86 }, align 1
+struct empty {};
+// PATTERN: @__const.test_small_uninit.uninit = private unnamed_addr constant %struct.small { i8 -86 }, align 1
+// PATTERN: @__const.test_small_custom.custom = private unnamed_addr constant %struct.small { i8 42 }, align 1
+// ZERO: @__const.test_small_custom.custom = private unnamed_addr constant %struct.small { i8 42 }, align 1
+struct small { char c; };
+// PATTERN: @__const.test_smallinit_uninit.uninit = private unnamed_addr constant %struct.smallinit { i8 -86 }, align 1
+// PATTERN: @__const.test_smallinit_braces.braces = private unnamed_addr constant %struct.smallinit { i8 -86 }, align 1
+// PATTERN: @__const.test_smallinit_custom.custom = private unnamed_addr constant %struct.smallinit { i8 -86 }, align 1
+struct smallinit { char c = 42; };
+// PATTERN: @__const.test_smallpartinit_uninit.uninit = private unnamed_addr constant %struct.smallpartinit { i8 -86, i8 -86 }, align 1
+// PATTERN: @__const.test_smallpartinit_braces.braces = private unnamed_addr constant %struct.smallpartinit { i8 -86, i8 -86 }, align 1
+// PATTERN: @__const.test_smallpartinit_custom.custom = private unnamed_addr constant %struct.smallpartinit { i8 -86, i8 -86 }, align 1
+struct smallpartinit { char c = 42, d; };
+// PATTERN: @__const.test_nullinit_uninit.uninit = private unnamed_addr constant %struct.nullinit { i8* inttoptr (i64 -6148914691236517206 to i8*) }, align 8
+// PATTERN: @__const.test_nullinit_braces.braces = private unnamed_addr constant %struct.nullinit { i8* inttoptr (i64 -6148914691236517206 to i8*) }, align 8
+// PATTERN: @__const.test_nullinit_custom.custom = private unnamed_addr constant %struct.nullinit { i8* inttoptr (i64 -6148914691236517206 to i8*) }, align 8
+struct nullinit { char* null = nullptr; };
+// PATTERN: @__const.test_padded_uninit.uninit = private unnamed_addr constant %struct.padded { i8 -86, i32 -1431655766 }, align 4
+// PATTERN: @__const.test_padded_custom.custom = private unnamed_addr constant %struct.padded { i8 42, i32 13371337 }, align 4
+// ZERO: @__const.test_padded_custom.custom = private unnamed_addr constant %struct.padded { i8 42, i32 13371337 }, align 4
+struct padded { char c; int i; };
+// PATTERN: @__const.test_paddednullinit_uninit.uninit = private unnamed_addr constant %struct.paddednullinit { i8 -86, i32 -1431655766 }, align 4
+// PATTERN: @__const.test_paddednullinit_braces.braces = private unnamed_addr constant %struct.paddednullinit { i8 -86, i32 -1431655766 }, align 4
+// PATTERN: @__const.test_paddednullinit_custom.custom = private unnamed_addr constant %struct.paddednullinit { i8 -86, i32 -1431655766 }, align 4
+struct paddednullinit { char c = 0; int i = 0; };
+// PATTERN: @__const.test_bitfield_uninit.uninit = private unnamed_addr constant %struct.bitfield { i8 -86, [3 x i8] c"\AA\AA\AA" }, align 4
+// PATTERN: @__const.test_bitfield_custom.custom = private unnamed_addr constant %struct.bitfield { i8 20, [3 x i8] zeroinitializer }, align 4
+// ZERO: @__const.test_bitfield_custom.custom = private unnamed_addr constant %struct.bitfield { i8 20, [3 x i8] zeroinitializer }, align 4
+struct bitfield { int i : 4; int j : 2; };
+// PATTERN: @__const.test_bitfieldaligned_uninit.uninit = private unnamed_addr constant %struct.bitfieldaligned { i8 -86, [3 x i8] c"\AA\AA\AA", i8 -86, [3 x i8] c"\AA\AA\AA" }, align 4
+// PATTERN: @__const.test_bitfieldaligned_custom.custom = private unnamed_addr constant %struct.bitfieldaligned { i8 4, [3 x i8] zeroinitializer, i8 1, [3 x i8] zeroinitializer }, align 4
+// ZERO: @__const.test_bitfieldaligned_custom.custom = private unnamed_addr constant %struct.bitfieldaligned { i8 4, [3 x i8] zeroinitializer, i8 1, [3 x i8] zeroinitializer }, align 4
+struct bitfieldaligned { int i : 4; int : 0; int j : 2; };
+struct big { unsigned a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z; };
+// PATTERN: @__const.test_arraytail_uninit.uninit = private unnamed_addr constant %struct.arraytail { i32 -1431655766, [0 x i32] zeroinitializer }, align 4
+// PATTERN: @__const.test_arraytail_custom.custom = private unnamed_addr constant %struct.arraytail { i32 57005, [0 x i32] zeroinitializer }, align 4
+// ZERO: @__const.test_arraytail_custom.custom = private unnamed_addr constant %struct.arraytail { i32 57005, [0 x i32] zeroinitializer }, align 4
+struct arraytail { int i; int arr[]; };
+// PATTERN: @__const.test_int1_uninit.uninit = private unnamed_addr constant [1 x i32] [i32 -1431655766], align 4
+// PATTERN: @__const.test_int1_custom.custom = private unnamed_addr constant [1 x i32] [i32 858993459], align 4
+// ZERO: @__const.test_int1_custom.custom = private unnamed_addr constant [1 x i32] [i32 858993459], align 4
+// PATTERN: @__const.test_bool4_uninit.uninit = private unnamed_addr constant [4 x i8] c"\AA\AA\AA\AA", align 1
+// PATTERN: @__const.test_bool4_custom.custom = private unnamed_addr constant [4 x i8] c"\01\01\01\01", align 1
+// ZERO: @__const.test_bool4_custom.custom = private unnamed_addr constant [4 x i8] c"\01\01\01\01", align 1
+// PATTERN: @__const.test_intptr4_uninit.uninit = private unnamed_addr constant [4 x i32*] [i32* inttoptr (i64 -6148914691236517206 to i32*), i32* inttoptr (i64 -6148914691236517206 to i32*), i32* inttoptr (i64 -6148914691236517206 to i32*), i32* inttoptr (i64 -6148914691236517206 to i32*)], align 16
+// PATTERN: @__const.test_intptr4_custom.custom = private unnamed_addr constant [4 x i32*] [i32* inttoptr (i64 572662306 to i32*), i32* inttoptr (i64 572662306 to i32*), i32* inttoptr (i64 572662306 to i32*), i32* inttoptr (i64 572662306 to i32*)], align 16
+// ZERO: @__const.test_intptr4_custom.custom = private unnamed_addr constant [4 x i32*] [i32* inttoptr (i64 572662306 to i32*), i32* inttoptr (i64 572662306 to i32*), i32* inttoptr (i64 572662306 to i32*), i32* inttoptr (i64 572662306 to i32*)], align 16
+// PATTERN: @__const.test_tailpad4_uninit.uninit = private unnamed_addr constant [4 x %struct.tailpad] [%struct.tailpad { i16 -21846, i8 -86 }, %struct.tailpad { i16 -21846, i8 -86 }, %struct.tailpad { i16 -21846, i8 -86 }, %struct.tailpad { i16 -21846, i8 -86 }], align 16
+// PATTERN: @__const.test_tailpad4_custom.custom = private unnamed_addr constant [4 x %struct.tailpad] [%struct.tailpad { i16 257, i8 1 }, %struct.tailpad { i16 257, i8 1 }, %struct.tailpad { i16 257, i8 1 }, %struct.tailpad { i16 257, i8 1 }], align 16
+// ZERO: @__const.test_tailpad4_custom.custom = private unnamed_addr constant [4 x %struct.tailpad] [%struct.tailpad { i16 257, i8 1 }, %struct.tailpad { i16 257, i8 1 }, %struct.tailpad { i16 257, i8 1 }, %struct.tailpad { i16 257, i8 1 }], align 16
+struct tailpad { short s; char c; };
+// PATTERN: @__const.test_atomicnotlockfree_uninit.uninit = private unnamed_addr constant %struct.notlockfree { [4 x i64] [i64 -6148914691236517206, i64 -6148914691236517206, i64 -6148914691236517206, i64 -6148914691236517206] }, align 8
+struct notlockfree { long long a[4]; };
+// PATTERN: @__const.test_atomicpadded_uninit.uninit = private unnamed_addr constant %struct.padded { i8 -86, i32 -1431655766 }, align 8
+// PATTERN: @__const.test_atomictailpad_uninit.uninit = private unnamed_addr constant %struct.tailpad { i16 -21846, i8 -86 }, align 4
+// PATTERN: @__const.test_complexfloat_uninit.uninit = private unnamed_addr constant { float, float } { float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000 }, align 4
+// PATTERN: @__const.test_complexfloat_braces.braces = private unnamed_addr constant { float, float } { float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000 }, align 4
+// PATTERN: @__const.test_complexfloat_custom.custom = private unnamed_addr constant { float, float } { float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000 }, align 4
+// PATTERN: @__const.test_complexdouble_uninit.uninit = private unnamed_addr constant { double, double } { double 0xFFFFFFFFFFFFFFFF, double 0xFFFFFFFFFFFFFFFF }, align 8
+// PATTERN: @__const.test_complexdouble_braces.braces = private unnamed_addr constant { double, double } { double 0xFFFFFFFFFFFFFFFF, double 0xFFFFFFFFFFFFFFFF }, align 8
+// PATTERN: @__const.test_complexdouble_custom.custom = private unnamed_addr constant { double, double } { double 0xFFFFFFFFFFFFFFFF, double 0xFFFFFFFFFFFFFFFF }, align 8
+// PATTERN: @__const.test_semivolatile_uninit.uninit = private unnamed_addr constant %struct.semivolatile { i32 -1431655766, i32 -1431655766 }, align 4
+// PATTERN: @__const.test_semivolatile_custom.custom = private unnamed_addr constant %struct.semivolatile { i32 1145324612, i32 1145324612 }, align 4
+struct semivolatile { int i; volatile int vi; };
+// PATTERN: @__const.test_semivolatileinit_uninit.uninit = private unnamed_addr constant %struct.semivolatileinit { i32 -1431655766, i32 -1431655766 }, align 4
+// PATTERN: @__const.test_semivolatileinit_braces.braces = private unnamed_addr constant %struct.semivolatileinit { i32 -1431655766, i32 -1431655766 }, align 4
+// PATTERN: @__const.test_semivolatileinit_custom.custom = private unnamed_addr constant %struct.semivolatileinit { i32 -1431655766, i32 -1431655766 }, align 4
+// ZERO: @__const.test_semivolatile_custom.custom = private unnamed_addr constant %struct.semivolatile { i32 1145324612, i32 1145324612 }, align 4
+struct semivolatileinit { int i = 0x11111111; volatile int vi = 0x11111111; };
+// PATTERN: @__const.test_base_uninit.uninit = private unnamed_addr constant %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) }, align 8
+// PATTERN: @__const.test_base_braces.braces = private unnamed_addr constant %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) }, align 8
+struct base { virtual ~base(); };
+// PATTERN: @__const.test_derived_uninit.uninit = private unnamed_addr constant %struct.derived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) } }, align 8
+// PATTERN: @__const.test_derived_braces.braces = private unnamed_addr constant %struct.derived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) } }, align 8
+struct derived : public base {};
+// PATTERN: @__const.test_virtualderived_uninit.uninit = private unnamed_addr constant %struct.virtualderived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) }, %struct.derived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) } } }, align 8
+// PATTERN: @__const.test_virtualderived_braces.braces = private unnamed_addr constant %struct.virtualderived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) }, %struct.derived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) } } }, align 8
+struct virtualderived : public virtual base, public virtual derived {};
+// PATTERN: @__const.test_matching_uninit.uninit = private unnamed_addr constant %union.matching { i32 -1431655766 }, align 4
+// PATTERN: @__const.test_matching_custom.custom = private unnamed_addr constant { float } { float 6.145500e+04 }, align 4
+union matching { int i; float f; };
+// PATTERN: @__const.test_matchingreverse_uninit.uninit = private unnamed_addr constant %union.matchingreverse { float 0xFFFFFFFFE0000000 }, align 4
+// PATTERN: @__const.test_matchingreverse_custom.custom = private unnamed_addr constant { i32 } { i32 61455 }, align 4
+// ZERO: @__const.test_matching_custom.custom = private unnamed_addr constant { float } { float 6.145500e+04 }, align 4
+union matchingreverse { float f; int i; };
+// PATTERN: @__const.test_unmatched_uninit.uninit = private unnamed_addr constant %union.unmatched { i32 -1431655766 }, align 4
+// PATTERN: @__const.test_unmatched_custom.custom = private unnamed_addr constant %union.unmatched { i32 1001242351 }, align 4
+// ZERO: @__const.test_matchingreverse_custom.custom = private unnamed_addr constant { i32 } { i32 61455 }, align 4
+union unmatched { char c; int i; };
+// PATTERN: @__const.test_unmatchedreverse_uninit.uninit = private unnamed_addr constant %union.unmatchedreverse { i32 -1431655766 }, align 4
+// PATTERN: @__const.test_unmatchedreverse_custom.custom = private unnamed_addr constant { i8, [3 x i8] } { i8 42, [3 x i8] zeroinitializer }, align 4
+// ZERO: @__const.test_unmatched_custom.custom = private unnamed_addr constant %union.unmatched { i32 1001242351 }, align 4
+union unmatchedreverse { int i; char c; };
+// PATTERN: @__const.test_unmatchedfp_uninit.uninit = private unnamed_addr constant %union.unmatchedfp { double 0xFFFFFFFFFFFFFFFF }, align 8
+// PATTERN: @__const.test_unmatchedfp_custom.custom = private unnamed_addr constant %union.unmatchedfp { double 0x400921FB54442D18 }, align 8
+// ZERO: @__const.test_unmatchedreverse_custom.custom = private unnamed_addr constant { i8, [3 x i8] } { i8 42, [3 x i8] zeroinitializer }, align 4
+// ZERO: @__const.test_unmatchedfp_custom.custom = private unnamed_addr constant %union.unmatchedfp { double 0x400921FB54442D18 }, align 8
+union unmatchedfp { float f; double d; };
+enum emptyenum {};
+enum smallenum { VALUE };
+
+extern "C" {
+
+TEST_UNINIT(char, char);
+// CHECK-LABEL: @test_char_uninit()
+// CHECK: %uninit = alloca i8, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_char_uninit()
+// PATTERN: store i8 -86, i8* %uninit, align 1
+// ZERO-LABEL: @test_char_uninit()
+// ZERO: store i8 0, i8* %uninit, align 1
+
+TEST_BRACES(char, char);
+// CHECK-LABEL: @test_char_braces()
+// CHECK: %braces = alloca i8, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store i8 0, i8* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(uchar, unsigned char);
+// CHECK-LABEL: @test_uchar_uninit()
+// CHECK: %uninit = alloca i8, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_uchar_uninit()
+// PATTERN: store i8 -86, i8* %uninit, align 1
+// ZERO-LABEL: @test_uchar_uninit()
+// ZERO: store i8 0, i8* %uninit, align 1
+
+TEST_BRACES(uchar, unsigned char);
+// CHECK-LABEL: @test_uchar_braces()
+// CHECK: %braces = alloca i8, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store i8 0, i8* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(schar, signed char);
+// CHECK-LABEL: @test_schar_uninit()
+// CHECK: %uninit = alloca i8, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_schar_uninit()
+// PATTERN: store i8 -86, i8* %uninit, align 1
+// ZERO-LABEL: @test_schar_uninit()
+// ZERO: store i8 0, i8* %uninit, align 1
+
+TEST_BRACES(schar, signed char);
+// CHECK-LABEL: @test_schar_braces()
+// CHECK: %braces = alloca i8, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store i8 0, i8* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(wchar_t, wchar_t);
+// CHECK-LABEL: @test_wchar_t_uninit()
+// CHECK: %uninit = alloca i32, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_wchar_t_uninit()
+// PATTERN: store i32 -1431655766, i32* %uninit, align
+// ZERO-LABEL: @test_wchar_t_uninit()
+// ZERO: store i32 0, i32* %uninit, align
+
+TEST_BRACES(wchar_t, wchar_t);
+// CHECK-LABEL: @test_wchar_t_braces()
+// CHECK: %braces = alloca i32, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store i32 0, i32* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(short, short);
+// CHECK-LABEL: @test_short_uninit()
+// CHECK: %uninit = alloca i16, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_short_uninit()
+// PATTERN: store i16 -21846, i16* %uninit, align
+// ZERO-LABEL: @test_short_uninit()
+// ZERO: store i16 0, i16* %uninit, align
+
+TEST_BRACES(short, short);
+// CHECK-LABEL: @test_short_braces()
+// CHECK: %braces = alloca i16, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store i16 0, i16* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(ushort, unsigned short);
+// CHECK-LABEL: @test_ushort_uninit()
+// CHECK: %uninit = alloca i16, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_ushort_uninit()
+// PATTERN: store i16 -21846, i16* %uninit, align
+// ZERO-LABEL: @test_ushort_uninit()
+// ZERO: store i16 0, i16* %uninit, align
+
+TEST_BRACES(ushort, unsigned short);
+// CHECK-LABEL: @test_ushort_braces()
+// CHECK: %braces = alloca i16, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store i16 0, i16* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(int, int);
+// CHECK-LABEL: @test_int_uninit()
+// CHECK: %uninit = alloca i32, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_int_uninit()
+// PATTERN: store i32 -1431655766, i32* %uninit, align
+// ZERO-LABEL: @test_int_uninit()
+// ZERO: store i32 0, i32* %uninit, align
+
+TEST_BRACES(int, int);
+// CHECK-LABEL: @test_int_braces()
+// CHECK: %braces = alloca i32, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store i32 0, i32* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(unsigned, unsigned);
+// CHECK-LABEL: @test_unsigned_uninit()
+// CHECK: %uninit = alloca i32, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_unsigned_uninit()
+// PATTERN: store i32 -1431655766, i32* %uninit, align
+// ZERO-LABEL: @test_unsigned_uninit()
+// ZERO: store i32 0, i32* %uninit, align
+
+TEST_BRACES(unsigned, unsigned);
+// CHECK-LABEL: @test_unsigned_braces()
+// CHECK: %braces = alloca i32, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store i32 0, i32* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(long, long);
+// CHECK-LABEL: @test_long_uninit()
+// CHECK: %uninit = alloca i64, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_long_uninit()
+// PATTERN: store i64 -6148914691236517206, i64* %uninit, align
+// ZERO-LABEL: @test_long_uninit()
+// ZERO: store i64 0, i64* %uninit, align
+
+TEST_BRACES(long, long);
+// CHECK-LABEL: @test_long_braces()
+// CHECK: %braces = alloca i64, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store i64 0, i64* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(ulong, unsigned long);
+// CHECK-LABEL: @test_ulong_uninit()
+// CHECK: %uninit = alloca i64, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_ulong_uninit()
+// PATTERN: store i64 -6148914691236517206, i64* %uninit, align
+// ZERO-LABEL: @test_ulong_uninit()
+// ZERO: store i64 0, i64* %uninit, align
+
+TEST_BRACES(ulong, unsigned long);
+// CHECK-LABEL: @test_ulong_braces()
+// CHECK: %braces = alloca i64, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store i64 0, i64* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(longlong, long long);
+// CHECK-LABEL: @test_longlong_uninit()
+// CHECK: %uninit = alloca i64, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_longlong_uninit()
+// PATTERN: store i64 -6148914691236517206, i64* %uninit, align
+// ZERO-LABEL: @test_longlong_uninit()
+// ZERO: store i64 0, i64* %uninit, align
+
+TEST_BRACES(longlong, long long);
+// CHECK-LABEL: @test_longlong_braces()
+// CHECK: %braces = alloca i64, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store i64 0, i64* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(ulonglong, unsigned long long);
+// CHECK-LABEL: @test_ulonglong_uninit()
+// CHECK: %uninit = alloca i64, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_ulonglong_uninit()
+// PATTERN: store i64 -6148914691236517206, i64* %uninit, align
+// ZERO-LABEL: @test_ulonglong_uninit()
+// ZERO: store i64 0, i64* %uninit, align
+
+TEST_BRACES(ulonglong, unsigned long long);
+// CHECK-LABEL: @test_ulonglong_braces()
+// CHECK: %braces = alloca i64, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store i64 0, i64* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(int128, __int128);
+// CHECK-LABEL: @test_int128_uninit()
+// CHECK: %uninit = alloca i128, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_int128_uninit()
+// PATTERN: store i128 -113427455640312821154458202477256070486, i128* %uninit, align
+// ZERO-LABEL: @test_int128_uninit()
+// ZERO: store i128 0, i128* %uninit, align
+
+TEST_BRACES(int128, __int128);
+// CHECK-LABEL: @test_int128_braces()
+// CHECK: %braces = alloca i128, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store i128 0, i128* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(uint128, unsigned __int128);
+// CHECK-LABEL: @test_uint128_uninit()
+// CHECK: %uninit = alloca i128, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_uint128_uninit()
+// PATTERN: store i128 -113427455640312821154458202477256070486, i128* %uninit, align
+// ZERO-LABEL: @test_uint128_uninit()
+// ZERO: store i128 0, i128* %uninit, align
+
+TEST_BRACES(uint128, unsigned __int128);
+// CHECK-LABEL: @test_uint128_braces()
+// CHECK: %braces = alloca i128, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store i128 0, i128* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+
+TEST_UNINIT(fp16, __fp16);
+// CHECK-LABEL: @test_fp16_uninit()
+// CHECK: %uninit = alloca half, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_fp16_uninit()
+// PATTERN: store half 0xHFFFF, half* %uninit, align
+// ZERO-LABEL: @test_fp16_uninit()
+// ZERO: store half 0xH0000, half* %uninit, align
+
+TEST_BRACES(fp16, __fp16);
+// CHECK-LABEL: @test_fp16_braces()
+// CHECK: %braces = alloca half, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store half 0xH0000, half* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(float, float);
+// CHECK-LABEL: @test_float_uninit()
+// CHECK: %uninit = alloca float, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_float_uninit()
+// PATTERN: store float 0xFFFFFFFFE0000000, float* %uninit, align
+// ZERO-LABEL: @test_float_uninit()
+// ZERO: store float 0.000000e+00, float* %uninit, align
+
+TEST_BRACES(float, float);
+// CHECK-LABEL: @test_float_braces()
+// CHECK: %braces = alloca float, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store float 0.000000e+00, float* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(double, double);
+// CHECK-LABEL: @test_double_uninit()
+// CHECK: %uninit = alloca double, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_double_uninit()
+// PATTERN: store double 0xFFFFFFFFFFFFFFFF, double* %uninit, align
+// ZERO-LABEL: @test_double_uninit()
+// ZERO: store double 0.000000e+00, double* %uninit, align
+
+TEST_BRACES(double, double);
+// CHECK-LABEL: @test_double_braces()
+// CHECK: %braces = alloca double, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store double 0.000000e+00, double* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(longdouble, long double);
+// CHECK-LABEL: @test_longdouble_uninit()
+// CHECK: %uninit = alloca x86_fp80, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_longdouble_uninit()
+// PATTERN: store x86_fp80 0xKFFFFFFFFFFFFFFFFFFFF, x86_fp80* %uninit, align
+// ZERO-LABEL: @test_longdouble_uninit()
+// ZERO: store x86_fp80 0xK00000000000000000000, x86_fp80* %uninit, align
+
+TEST_BRACES(longdouble, long double);
+// CHECK-LABEL: @test_longdouble_braces()
+// CHECK: %braces = alloca x86_fp80, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store x86_fp80 0xK00000000000000000000, x86_fp80* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+
+TEST_UNINIT(intptr, int*);
+// CHECK-LABEL: @test_intptr_uninit()
+// CHECK: %uninit = alloca i32*, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_intptr_uninit()
+// PATTERN: store i32* inttoptr (i64 -6148914691236517206 to i32*), i32** %uninit, align
+// ZERO-LABEL: @test_intptr_uninit()
+// ZERO: store i32* null, i32** %uninit, align
+
+TEST_BRACES(intptr, int*);
+// CHECK-LABEL: @test_intptr_braces()
+// CHECK: %braces = alloca i32*, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store i32* null, i32** %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(intptrptr, int**);
+// CHECK-LABEL: @test_intptrptr_uninit()
+// CHECK: %uninit = alloca i32**, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_intptrptr_uninit()
+// PATTERN: store i32** inttoptr (i64 -6148914691236517206 to i32**), i32*** %uninit, align
+// ZERO-LABEL: @test_intptrptr_uninit()
+// ZERO: store i32** null, i32*** %uninit, align
+
+TEST_BRACES(intptrptr, int**);
+// CHECK-LABEL: @test_intptrptr_braces()
+// CHECK: %braces = alloca i32**, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store i32** null, i32*** %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(function, void(*)());
+// CHECK-LABEL: @test_function_uninit()
+// CHECK: %uninit = alloca void ()*, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_function_uninit()
+// PATTERN: store void ()* inttoptr (i64 -6148914691236517206 to void ()*), void ()** %uninit, align
+// ZERO-LABEL: @test_function_uninit()
+// ZERO: store void ()* null, void ()** %uninit, align
+
+TEST_BRACES(function, void(*)());
+// CHECK-LABEL: @test_function_braces()
+// CHECK: %braces = alloca void ()*, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store void ()* null, void ()** %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(bool, bool);
+// CHECK-LABEL: @test_bool_uninit()
+// CHECK: %uninit = alloca i8, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_bool_uninit()
+// PATTERN: store i8 -86, i8* %uninit, align 1
+// ZERO-LABEL: @test_bool_uninit()
+// ZERO: store i8 0, i8* %uninit, align 1
+
+TEST_BRACES(bool, bool);
+// CHECK-LABEL: @test_bool_braces()
+// CHECK: %braces = alloca i8, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store i8 0, i8* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+
+TEST_UNINIT(empty, empty);
+// CHECK-LABEL: @test_empty_uninit()
+// CHECK: %uninit = alloca %struct.empty, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_empty_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_empty_uninit.uninit
+// ZERO-LABEL: @test_empty_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(empty, empty);
+// CHECK-LABEL: @test_empty_braces()
+// CHECK: %braces = alloca %struct.empty, align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(small, small);
+// CHECK-LABEL: @test_small_uninit()
+// CHECK: %uninit = alloca %struct.small, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_small_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_small_uninit.uninit
+// ZERO-LABEL: @test_small_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(small, small);
+// CHECK-LABEL: @test_small_braces()
+// CHECK: %braces = alloca %struct.small, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 1, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(small, small, { 42 });
+// CHECK-LABEL: @test_small_custom()
+// CHECK: %custom = alloca %struct.small, align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(smallinit, smallinit);
+// CHECK-LABEL: @test_smallinit_uninit()
+// CHECK: %uninit = alloca %struct.smallinit, align
+// CHECK-NEXT: call void @{{.*}}smallinit{{.*}}%uninit)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+
+TEST_BRACES(smallinit, smallinit);
+// CHECK-LABEL: @test_smallinit_braces()
+// CHECK: %braces = alloca %struct.smallinit, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: %[[C:[^ ]*]] = getelementptr inbounds %struct.smallinit, %struct.smallinit* %braces, i32 0, i32 0
+// CHECK-NEXT: store i8 42, i8* %[[C]], align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(smallinit, smallinit, { 100 });
+// CHECK-LABEL: @test_smallinit_custom()
+// CHECK: %custom = alloca %struct.smallinit, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: %[[C:[^ ]*]] = getelementptr inbounds %struct.smallinit, %struct.smallinit* %custom, i32 0, i32 0
+// CHECK-NEXT: store i8 100, i8* %[[C]], align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(smallpartinit, smallpartinit);
+// CHECK-LABEL: @test_smallpartinit_uninit()
+// CHECK: %uninit = alloca %struct.smallpartinit, align
+// CHECK-NEXT: call void @{{.*}}smallpartinit{{.*}}%uninit)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_smallpartinit_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_smallpartinit_uninit.uninit
+// ZERO-LABEL: @test_smallpartinit_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(smallpartinit, smallpartinit);
+// CHECK-LABEL: @test_smallpartinit_braces()
+// CHECK: %braces = alloca %struct.smallpartinit, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: %[[C:[^ ]*]] = getelementptr inbounds %struct.smallpartinit, %struct.smallpartinit* %braces, i32 0, i32 0
+// CHECK-NEXT: store i8 42, i8* %[[C]], align [[ALIGN]]
+// CHECK-NEXT: %[[D:[^ ]*]] = getelementptr inbounds %struct.smallpartinit, %struct.smallpartinit* %braces, i32 0, i32 1
+// CHECK-NEXT: store i8 0, i8* %[[D]], align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(smallpartinit, smallpartinit, { 100, 42 });
+// CHECK-LABEL: @test_smallpartinit_custom()
+// CHECK: %custom = alloca %struct.smallpartinit, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: %[[C:[^ ]*]] = getelementptr inbounds %struct.smallpartinit, %struct.smallpartinit* %custom, i32 0, i32 0
+// CHECK-NEXT: store i8 100, i8* %[[C]], align [[ALIGN]]
+// CHECK-NEXT: %[[D:[^ ]*]] = getelementptr inbounds %struct.smallpartinit, %struct.smallpartinit* %custom, i32 0, i32 1
+// CHECK-NEXT: store i8 42, i8* %[[D]], align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(nullinit, nullinit);
+// CHECK-LABEL: @test_nullinit_uninit()
+// CHECK: %uninit = alloca %struct.nullinit, align
+// CHECK-NEXT: call void @{{.*}}nullinit{{.*}}%uninit)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+
+TEST_BRACES(nullinit, nullinit);
+// CHECK-LABEL: @test_nullinit_braces()
+// CHECK: %braces = alloca %struct.nullinit, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: %[[N:[^ ]*]] = getelementptr inbounds %struct.nullinit, %struct.nullinit* %braces, i32 0, i32 0
+// CHECK-NEXT: store i8* null, i8** %[[N]], align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(nullinit, nullinit, { (char*)"derp" });
+// CHECK-LABEL: @test_nullinit_custom()
+// CHECK: %custom = alloca %struct.nullinit, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: %[[N:[^ ]*]] = getelementptr inbounds %struct.nullinit, %struct.nullinit* %custom, i32 0, i32 0
+// CHECK-NEXT: store i8* getelementptr inbounds {{.*}}, i8** %[[N]], align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(padded, padded);
+// CHECK-LABEL: @test_padded_uninit()
+// CHECK: %uninit = alloca %struct.padded, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_padded_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_padded_uninit.uninit
+// ZERO-LABEL: @test_padded_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(padded, padded);
+// CHECK-LABEL: @test_padded_braces()
+// CHECK: %braces = alloca %struct.padded, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 8, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(padded, padded, { 42, 13371337 });
+// CHECK-LABEL: @test_padded_custom()
+// CHECK: %custom = alloca %struct.padded, align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(paddednullinit, paddednullinit);
+// CHECK-LABEL: @test_paddednullinit_uninit()
+// CHECK: %uninit = alloca %struct.paddednullinit, align
+// CHECK-NEXT: call void @{{.*}}paddednullinit{{.*}}%uninit)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_paddednullinit_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_paddednullinit_uninit.uninit
+// ZERO-LABEL: @test_paddednullinit_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(paddednullinit, paddednullinit);
+// CHECK-LABEL: @test_paddednullinit_braces()
+// CHECK: %braces = alloca %struct.paddednullinit, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: %[[C:[^ ]*]] = getelementptr inbounds %struct.paddednullinit, %struct.paddednullinit* %braces, i32 0, i32 0
+// CHECK-NEXT: store i8 0, i8* %[[C]], align [[ALIGN]]
+// CHECK-NEXT: %[[I:[^ ]*]] = getelementptr inbounds %struct.paddednullinit, %struct.paddednullinit* %braces, i32 0, i32 1
+// CHECK-NEXT: store i32 0, i32* %[[I]], align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(paddednullinit, paddednullinit, { 42, 13371337 });
+// CHECK-LABEL: @test_paddednullinit_custom()
+// CHECK: %custom = alloca %struct.paddednullinit, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: %[[C:[^ ]*]] = getelementptr inbounds %struct.paddednullinit, %struct.paddednullinit* %custom, i32 0, i32 0
+// CHECK-NEXT: store i8 42, i8* %[[C]], align [[ALIGN]]
+// CHECK-NEXT: %[[I:[^ ]*]] = getelementptr inbounds %struct.paddednullinit, %struct.paddednullinit* %custom, i32 0, i32 1
+// CHECK-NEXT: store i32 13371337, i32* %[[I]], align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(bitfield, bitfield);
+// CHECK-LABEL: @test_bitfield_uninit()
+// CHECK: %uninit = alloca %struct.bitfield, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_bitfield_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_bitfield_uninit.uninit
+// ZERO-LABEL: @test_bitfield_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(bitfield, bitfield);
+// CHECK-LABEL: @test_bitfield_braces()
+// CHECK: %braces = alloca %struct.bitfield, align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(bitfield, bitfield, { 4, 1 });
+// CHECK-LABEL: @test_bitfield_custom()
+// CHECK: %custom = alloca %struct.bitfield, align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(bitfieldaligned, bitfieldaligned);
+// CHECK-LABEL: @test_bitfieldaligned_uninit()
+// CHECK: %uninit = alloca %struct.bitfieldaligned, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_bitfieldaligned_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_bitfieldaligned_uninit.uninit
+// ZERO-LABEL: @test_bitfieldaligned_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(bitfieldaligned, bitfieldaligned);
+// CHECK-LABEL: @test_bitfieldaligned_braces()
+// CHECK: %braces = alloca %struct.bitfieldaligned, align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(bitfieldaligned, bitfieldaligned, { 4, 1 });
+// CHECK-LABEL: @test_bitfieldaligned_custom()
+// CHECK: %custom = alloca %struct.bitfieldaligned, align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(big, big);
+// CHECK-LABEL: @test_big_uninit()
+// CHECK: %uninit = alloca %struct.big, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_big_uninit()
+// PATTERN: call void @llvm.memset{{.*}}, i8 -86,
+// ZERO-LABEL: @test_big_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(big, big);
+// CHECK-LABEL: @test_big_braces()
+// CHECK: %braces = alloca %struct.big, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 104, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(big, big, { 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA });
+// CHECK-LABEL: @test_big_custom()
+// CHECK: %custom = alloca %struct.big, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 -86, i64 104, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(arraytail, arraytail);
+// CHECK-LABEL: @test_arraytail_uninit()
+// CHECK: %uninit = alloca %struct.arraytail, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_arraytail_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_arraytail_uninit.uninit
+// ZERO-LABEL: @test_arraytail_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(arraytail, arraytail);
+// CHECK-LABEL: @test_arraytail_braces()
+// CHECK: %braces = alloca %struct.arraytail, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 4, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(arraytail, arraytail, { 0xdead });
+// CHECK-LABEL: @test_arraytail_custom()
+// CHECK: %custom = alloca %struct.arraytail, align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+
+TEST_UNINIT(int0, int[0]);
+// CHECK-LABEL: @test_int0_uninit()
+// CHECK: %uninit = alloca [0 x i32], align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_int0_uninit()
+// PATTERN: %uninit = alloca [0 x i32], align
+// PATTERN-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// ZERO-LABEL: @test_int0_uninit()
+// ZERO: %uninit = alloca [0 x i32], align
+// ZERO-NEXT: call void @{{.*}}used{{.*}}%uninit)
+
+TEST_BRACES(int0, int[0]);
+// CHECK-LABEL: @test_int0_braces()
+// CHECK: %braces = alloca [0 x i32], align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 0, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(int1, int[1]);
+// CHECK-LABEL: @test_int1_uninit()
+// CHECK: %uninit = alloca [1 x i32], align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_int1_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_int1_uninit.uninit
+// ZERO-LABEL: @test_int1_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(int1, int[1]);
+// CHECK-LABEL: @test_int1_braces()
+// CHECK: %braces = alloca [1 x i32], align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 4, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(int1, int[1], { 0x33333333 });
+// CHECK-LABEL: @test_int1_custom()
+// CHECK: %custom = alloca [1 x i32], align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(int64, int[64]);
+// CHECK-LABEL: @test_int64_uninit()
+// CHECK: %uninit = alloca [64 x i32], align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_int64_uninit()
+// PATTERN: call void @llvm.memset{{.*}}, i8 -86,
+// ZERO-LABEL: @test_int64_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(int64, int[64]);
+// CHECK-LABEL: @test_int64_braces()
+// CHECK: %braces = alloca [64 x i32], align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 256, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(int64, int[64], = { 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0x11111111 });
+// CHECK-LABEL: @test_int64_custom()
+// CHECK: %custom = alloca [64 x i32], align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 17, i64 256, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(bool4, bool[4]);
+// CHECK-LABEL: @test_bool4_uninit()
+// CHECK: %uninit = alloca [4 x i8], align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_bool4_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_bool4_uninit.uninit
+// ZERO-LABEL: @test_bool4_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(bool4, bool[4]);
+// CHECK-LABEL: @test_bool4_braces()
+// CHECK: %braces = alloca [4 x i8], align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 4, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(bool4, bool[4], { true, true, true, true });
+// CHECK-LABEL: @test_bool4_custom()
+// CHECK: %custom = alloca [4 x i8], align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(intptr4, int*[4]);
+// CHECK-LABEL: @test_intptr4_uninit()
+// CHECK: %uninit = alloca [4 x i32*], align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_intptr4_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_intptr4_uninit.uninit
+// ZERO-LABEL: @test_intptr4_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(intptr4, int*[4]);
+// CHECK-LABEL: @test_intptr4_braces()
+// CHECK: %braces = alloca [4 x i32*], align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 32, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+ TEST_CUSTOM(intptr4, int*[4], = { (int*)0x22222222, (int*)0x22222222, (int*)0x22222222, (int*)0x22222222 });
+// CHECK-LABEL: @test_intptr4_custom()
+// CHECK: %custom = alloca [4 x i32*], align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(tailpad4, tailpad[4]);
+// CHECK-LABEL: @test_tailpad4_uninit()
+// CHECK: %uninit = alloca [4 x %struct.tailpad], align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_tailpad4_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_tailpad4_uninit.uninit
+// ZERO-LABEL: @test_tailpad4_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(tailpad4, tailpad[4]);
+// CHECK-LABEL: @test_tailpad4_braces()
+// CHECK: %braces = alloca [4 x %struct.tailpad], align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 16, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(tailpad4, tailpad[4], { {257, 1}, {257, 1}, {257, 1}, {257, 1} });
+// CHECK-LABEL: @test_tailpad4_custom()
+// CHECK: %custom = alloca [4 x %struct.tailpad], align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(tailpad9, tailpad[9]);
+// CHECK-LABEL: @test_tailpad9_uninit()
+// CHECK: %uninit = alloca [9 x %struct.tailpad], align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_tailpad9_uninit()
+// PATTERN: call void @llvm.memset{{.*}}, i8 -86,
+// ZERO-LABEL: @test_tailpad9_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(tailpad9, tailpad[9]);
+// CHECK-LABEL: @test_tailpad9_braces()
+// CHECK: %braces = alloca [9 x %struct.tailpad], align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 36, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(tailpad9, tailpad[9], { {257, 1}, {257, 1}, {257, 1}, {257, 1}, {257, 1}, {257, 1}, {257, 1}, {257, 1}, {257, 1} });
+// CHECK-LABEL: @test_tailpad9_custom()
+// CHECK: %custom = alloca [9 x %struct.tailpad], align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 1, i64 36, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+
+TEST_UNINIT(atomicbool, _Atomic(bool));
+// CHECK-LABEL: @test_atomicbool_uninit()
+// CHECK: %uninit = alloca i8, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_atomicbool_uninit()
+// PATTERN: store i8 -86, i8* %uninit, align 1
+// ZERO-LABEL: @test_atomicbool_uninit()
+// ZERO: store i8 0, i8* %uninit, align 1
+
+TEST_UNINIT(atomicint, _Atomic(int));
+// CHECK-LABEL: @test_atomicint_uninit()
+// CHECK: %uninit = alloca i32, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_atomicint_uninit()
+// PATTERN: store i32 -1431655766, i32* %uninit, align 4
+// ZERO-LABEL: @test_atomicint_uninit()
+// ZERO: store i32 0, i32* %uninit, align 4
+
+TEST_UNINIT(atomicdouble, _Atomic(double));
+// CHECK-LABEL: @test_atomicdouble_uninit()
+// CHECK: %uninit = alloca double, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_atomicdouble_uninit()
+// PATTERN: store double 0xFFFFFFFFFFFFFFFF, double* %uninit, align 8
+// ZERO-LABEL: @test_atomicdouble_uninit()
+// ZERO: store double 0.000000e+00, double* %uninit, align 8
+
+TEST_UNINIT(atomicnotlockfree, _Atomic(notlockfree));
+// CHECK-LABEL: @test_atomicnotlockfree_uninit()
+// CHECK: %uninit = alloca %struct.notlockfree, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_atomicnotlockfree_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_atomicnotlockfree_uninit.uninit
+// ZERO-LABEL: @test_atomicnotlockfree_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_UNINIT(atomicpadded, _Atomic(padded));
+// CHECK-LABEL: @test_atomicpadded_uninit()
+// CHECK: %uninit = alloca %struct.padded, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_atomicpadded_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_atomicpadded_uninit.uninit
+// ZERO-LABEL: @test_atomicpadded_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_UNINIT(atomictailpad, _Atomic(tailpad));
+// CHECK-LABEL: @test_atomictailpad_uninit()
+// CHECK: %uninit = alloca %struct.tailpad, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_atomictailpad_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_atomictailpad_uninit.uninit
+// ZERO-LABEL: @test_atomictailpad_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+
+TEST_UNINIT(complexfloat, _Complex float);
+// CHECK-LABEL: @test_complexfloat_uninit()
+// CHECK: %uninit = alloca { float, float }, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_complexfloat_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_complexfloat_uninit.uninit
+// ZERO-LABEL: @test_complexfloat_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(complexfloat, _Complex float);
+// CHECK-LABEL: @test_complexfloat_braces()
+// CHECK: %braces = alloca { float, float }, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: %[[R:[^ ]*]] = getelementptr inbounds { float, float }, { float, float }* %braces, i32 0, i32 0
+// CHECK-NEXT: %[[I:[^ ]*]] = getelementptr inbounds { float, float }, { float, float }* %braces, i32 0, i32 1
+// CHECK-NEXT: store float 0.000000e+00, float* %[[R]], align [[ALIGN]]
+// CHECK-NEXT: store float 0.000000e+00, float* %[[I]], align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(complexfloat, _Complex float, { 3.1415926535897932384626433, 3.1415926535897932384626433 });
+// CHECK-LABEL: @test_complexfloat_custom()
+// CHECK: %custom = alloca { float, float }, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: %[[R:[^ ]*]] = getelementptr inbounds { float, float }, { float, float }* %custom, i32 0, i32 0
+// CHECK-NEXT: %[[I:[^ ]*]] = getelementptr inbounds { float, float }, { float, float }* %custom, i32 0, i32 1
+// CHECK-NEXT: store float 0x400921FB60000000, float* %[[R]], align [[ALIGN]]
+// CHECK-NEXT: store float 0x400921FB60000000, float* %[[I]], align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(complexdouble, _Complex double);
+// CHECK-LABEL: @test_complexdouble_uninit()
+// CHECK: %uninit = alloca { double, double }, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_complexdouble_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_complexdouble_uninit.uninit
+// ZERO-LABEL: @test_complexdouble_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(complexdouble, _Complex double);
+// CHECK-LABEL: @test_complexdouble_braces()
+// CHECK: %braces = alloca { double, double }, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: %[[R:[^ ]*]] = getelementptr inbounds { double, double }, { double, double }* %braces, i32 0, i32 0
+// CHECK-NEXT: %[[I:[^ ]*]] = getelementptr inbounds { double, double }, { double, double }* %braces, i32 0, i32 1
+// CHECK-NEXT: store double 0.000000e+00, double* %[[R]], align [[ALIGN]]
+// CHECK-NEXT: store double 0.000000e+00, double* %[[I]], align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(complexdouble, _Complex double, { 3.1415926535897932384626433, 3.1415926535897932384626433 });
+// CHECK-LABEL: @test_complexdouble_custom()
+// CHECK: %custom = alloca { double, double }, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: %[[R:[^ ]*]] = getelementptr inbounds { double, double }, { double, double }* %custom, i32 0, i32 0
+// CHECK-NEXT: %[[I:[^ ]*]] = getelementptr inbounds { double, double }, { double, double }* %custom, i32 0, i32 1
+// CHECK-NEXT: store double 0x400921FB54442D18, double* %[[R]], align [[ALIGN]]
+// CHECK-NEXT: store double 0x400921FB54442D18, double* %[[I]], align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+
+TEST_UNINIT(volatileint, volatile int);
+// CHECK-LABEL: @test_volatileint_uninit()
+// CHECK: %uninit = alloca i32, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_volatileint_uninit()
+// PATTERN: store volatile i32 -1431655766, i32* %uninit, align 4
+// ZERO-LABEL: @test_volatileint_uninit()
+// ZERO: store volatile i32 0, i32* %uninit, align 4
+
+TEST_BRACES(volatileint, volatile int);
+// CHECK-LABEL: @test_volatileint_braces()
+// CHECK: %braces = alloca i32, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store volatile i32 0, i32* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(semivolatile, semivolatile);
+// CHECK-LABEL: @test_semivolatile_uninit()
+// CHECK: %uninit = alloca %struct.semivolatile, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_semivolatile_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_semivolatile_uninit.uninit
+// ZERO-LABEL: @test_semivolatile_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(semivolatile, semivolatile);
+// CHECK-LABEL: @test_semivolatile_braces()
+// CHECK: %braces = alloca %struct.semivolatile, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 8, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(semivolatile, semivolatile, { 0x44444444, 0x44444444 });
+// CHECK-LABEL: @test_semivolatile_custom()
+// CHECK: %custom = alloca %struct.semivolatile, align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(semivolatileinit, semivolatileinit);
+// CHECK-LABEL: @test_semivolatileinit_uninit()
+// CHECK: %uninit = alloca %struct.semivolatileinit, align
+// CHECK-NEXT: call void @{{.*}}semivolatileinit{{.*}}%uninit)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+
+TEST_BRACES(semivolatileinit, semivolatileinit);
+// CHECK-LABEL: @test_semivolatileinit_braces()
+// CHECK: %braces = alloca %struct.semivolatileinit, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: %[[I:[^ ]*]] = getelementptr inbounds %struct.semivolatileinit, %struct.semivolatileinit* %braces, i32 0, i32 0
+// CHECK-NEXT: store i32 286331153, i32* %[[I]], align [[ALIGN]]
+// CHECK-NEXT: %[[VI:[^ ]*]] = getelementptr inbounds %struct.semivolatileinit, %struct.semivolatileinit* %braces, i32 0, i32 1
+// CHECK-NEXT: store volatile i32 286331153, i32* %[[VI]], align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(semivolatileinit, semivolatileinit, { 0x44444444, 0x44444444 });
+// CHECK-LABEL: @test_semivolatileinit_custom()
+// CHECK: %custom = alloca %struct.semivolatileinit, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: %[[I:[^ ]*]] = getelementptr inbounds %struct.semivolatileinit, %struct.semivolatileinit* %custom, i32 0, i32 0
+// CHECK-NEXT: store i32 1145324612, i32* %[[I]], align [[ALIGN]]
+// CHECK-NEXT: %[[VI:[^ ]*]] = getelementptr inbounds %struct.semivolatileinit, %struct.semivolatileinit* %custom, i32 0, i32 1
+// CHECK-NEXT: store volatile i32 1145324612, i32* %[[VI]], align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+
+TEST_UNINIT(base, base);
+// CHECK-LABEL: @test_base_uninit()
+// CHECK: %uninit = alloca %struct.base, align
+// CHECK-NEXT: call void @{{.*}}base{{.*}}%uninit)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_base_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_base_uninit.uninit
+// ZERO-LABEL: @test_base_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(base, base);
+// CHECK-LABEL: @test_base_braces()
+// CHECK: %braces = alloca %struct.base, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 8, i1 false)
+// CHECK-NEXT: call void @{{.*}}base{{.*}}%braces)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(derived, derived);
+// CHECK-LABEL: @test_derived_uninit()
+// CHECK: %uninit = alloca %struct.derived, align
+// CHECK-NEXT: call void @{{.*}}derived{{.*}}%uninit)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_derived_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_derived_uninit.uninit
+// ZERO-LABEL: @test_derived_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(derived, derived);
+// CHECK-LABEL: @test_derived_braces()
+// CHECK: %braces = alloca %struct.derived, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 8, i1 false)
+// CHECK-NEXT: call void @{{.*}}derived{{.*}}%braces)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_UNINIT(virtualderived, virtualderived);
+// CHECK-LABEL: @test_virtualderived_uninit()
+// CHECK: %uninit = alloca %struct.virtualderived, align
+// CHECK-NEXT: call void @{{.*}}virtualderived{{.*}}%uninit)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_virtualderived_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_virtualderived_uninit.uninit
+// ZERO-LABEL: @test_virtualderived_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(virtualderived, virtualderived);
+// CHECK-LABEL: @test_virtualderived_braces()
+// CHECK: %braces = alloca %struct.virtualderived, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 16, i1 false)
+// CHECK-NEXT: call void @{{.*}}virtualderived{{.*}}%braces)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+
+TEST_UNINIT(matching, matching);
+// CHECK-LABEL: @test_matching_uninit()
+// CHECK: %uninit = alloca %union.matching, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_matching_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_matching_uninit.uninit
+// ZERO-LABEL: @test_matching_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(matching, matching);
+// CHECK-LABEL: @test_matching_braces()
+// CHECK: %braces = alloca %union.matching, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 4, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(matching, matching, { .f = 0xf00f });
+// CHECK-LABEL: @test_matching_custom()
+// CHECK: %custom = alloca %union.matching, align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(matchingreverse, matchingreverse);
+// CHECK-LABEL: @test_matchingreverse_uninit()
+// CHECK: %uninit = alloca %union.matchingreverse, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_matchingreverse_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_matchingreverse_uninit.uninit
+// ZERO-LABEL: @test_matchingreverse_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(matchingreverse, matchingreverse);
+// CHECK-LABEL: @test_matchingreverse_braces()
+// CHECK: %braces = alloca %union.matchingreverse, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 4, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(matchingreverse, matchingreverse, { .i = 0xf00f });
+// CHECK-LABEL: @test_matchingreverse_custom()
+// CHECK: %custom = alloca %union.matchingreverse, align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(unmatched, unmatched);
+// CHECK-LABEL: @test_unmatched_uninit()
+// CHECK: %uninit = alloca %union.unmatched, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_unmatched_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_unmatched_uninit.uninit
+// ZERO-LABEL: @test_unmatched_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(unmatched, unmatched);
+// CHECK-LABEL: @test_unmatched_braces()
+// CHECK: %braces = alloca %union.unmatched, align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(unmatched, unmatched, { .i = 0x3badbeef });
+// CHECK-LABEL: @test_unmatched_custom()
+// CHECK: %custom = alloca %union.unmatched, align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(unmatchedreverse, unmatchedreverse);
+// CHECK-LABEL: @test_unmatchedreverse_uninit()
+// CHECK: %uninit = alloca %union.unmatchedreverse, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_unmatchedreverse_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_unmatchedreverse_uninit.uninit
+// ZERO-LABEL: @test_unmatchedreverse_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(unmatchedreverse, unmatchedreverse);
+// CHECK-LABEL: @test_unmatchedreverse_braces()
+// CHECK: %braces = alloca %union.unmatchedreverse, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 4, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(unmatchedreverse, unmatchedreverse, { .c = 42 });
+// CHECK-LABEL: @test_unmatchedreverse_custom()
+// CHECK: %custom = alloca %union.unmatchedreverse, align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(unmatchedfp, unmatchedfp);
+// CHECK-LABEL: @test_unmatchedfp_uninit()
+// CHECK: %uninit = alloca %union.unmatchedfp, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_unmatchedfp_uninit()
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_unmatchedfp_uninit.uninit
+// ZERO-LABEL: @test_unmatchedfp_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(unmatchedfp, unmatchedfp);
+// CHECK-LABEL: @test_unmatchedfp_braces()
+// CHECK: %braces = alloca %union.unmatchedfp, align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(unmatchedfp, unmatchedfp, { .d = 3.1415926535897932384626433 });
+// CHECK-LABEL: @test_unmatchedfp_custom()
+// CHECK: %custom = alloca %union.unmatchedfp, align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+
+TEST_UNINIT(emptyenum, emptyenum);
+// CHECK-LABEL: @test_emptyenum_uninit()
+// CHECK: %uninit = alloca i32, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_emptyenum_uninit()
+// PATTERN: store i32 -1431655766, i32* %braces, align 4
+// ZERO-LABEL: @test_emptyenum_uninit()
+// ZERO: store i32 0, i32* %braces, align 4
+
+TEST_BRACES(emptyenum, emptyenum);
+// CHECK-LABEL: @test_emptyenum_braces()
+// CHECK: %braces = alloca i32, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store i32 0, i32* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(emptyenum, emptyenum, { (emptyenum)42 });
+// CHECK-LABEL: @test_emptyenum_custom()
+// CHECK: %custom = alloca i32, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store i32 42, i32* %custom, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(smallenum, smallenum);
+// CHECK-LABEL: @test_smallenum_uninit()
+// CHECK: %uninit = alloca i32, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_smallenum_uninit()
+// PATTERN: store i32 -1431655766, i32* %braces, align 4
+// ZERO-LABEL: @test_smallenum_uninit()
+// ZERO: store i32 0, i32* %braces, align 4
+
+TEST_BRACES(smallenum, smallenum);
+// CHECK-LABEL: @test_smallenum_braces()
+// CHECK: %braces = alloca i32, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store i32 0, i32* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(smallenum, smallenum, { (smallenum)42 });
+// CHECK-LABEL: @test_smallenum_custom()
+// CHECK: %custom = alloca i32, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store i32 42, i32* %custom, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+
+TEST_UNINIT(intvec16, int __attribute__((vector_size(16))));
+// CHECK-LABEL: @test_intvec16_uninit()
+// CHECK: %uninit = alloca <4 x i32>, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_intvec16_uninit()
+// PATTERN: store <4 x i32> <i32 -1431655766, i32 -1431655766, i32 -1431655766, i32 -1431655766>, <4 x i32>* %uninit, align 16
+// ZERO-LABEL: @test_intvec16_uninit()
+// ZERO: store <4 x i32> zeroinitializer, <4 x i32>* %uninit, align 16
+
+TEST_BRACES(intvec16, int __attribute__((vector_size(16))));
+// CHECK-LABEL: @test_intvec16_braces()
+// CHECK: %braces = alloca <4 x i32>, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store <4 x i32> zeroinitializer, <4 x i32>* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(intvec16, int __attribute__((vector_size(16))), { 0x44444444, 0x44444444, 0x44444444, 0x44444444 });
+// CHECK-LABEL: @test_intvec16_custom()
+// CHECK: %custom = alloca <4 x i32>, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store <4 x i32> <i32 1145324612, i32 1145324612, i32 1145324612, i32 1145324612>, <4 x i32>* %custom, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(longlongvec32, long long __attribute__((vector_size(32))));
+// CHECK-LABEL: @test_longlongvec32_uninit()
+// CHECK: %uninit = alloca <4 x i64>, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_longlongvec32_uninit()
+// PATTERN: store <4 x i64> <i64 -6148914691236517206, i64 -6148914691236517206, i64 -6148914691236517206, i64 -6148914691236517206>, <4 x i64>* %uninit, align 32
+// ZERO-LABEL: @test_longlongvec32_uninit()
+// ZERO: store <4 x i64> zeroinitializer, <4 x i64>* %uninit, align 32
+
+TEST_BRACES(longlongvec32, long long __attribute__((vector_size(32))));
+// CHECK-LABEL: @test_longlongvec32_braces()
+// CHECK: %braces = alloca <4 x i64>, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store <4 x i64> zeroinitializer, <4 x i64>* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(longlongvec32, long long __attribute__((vector_size(32))), { 0x3333333333333333, 0x3333333333333333, 0x3333333333333333, 0x3333333333333333 });
+// CHECK-LABEL: @test_longlongvec32_custom()
+// CHECK: %custom = alloca <4 x i64>, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store <4 x i64> <i64 3689348814741910323, i64 3689348814741910323, i64 3689348814741910323, i64 3689348814741910323>, <4 x i64>* %custom, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(floatvec16, float __attribute__((vector_size(16))));
+// CHECK-LABEL: @test_floatvec16_uninit()
+// CHECK: %uninit = alloca <4 x float>, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_floatvec16_uninit()
+// PATTERN: store <4 x float> <float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000>, <4 x float>* %uninit, align 16
+// ZERO-LABEL: @test_floatvec16_uninit()
+// ZERO: store <4 x float> zeroinitializer, <4 x float>* %uninit, align 16
+
+TEST_BRACES(floatvec16, float __attribute__((vector_size(16))));
+// CHECK-LABEL: @test_floatvec16_braces()
+// CHECK: %braces = alloca <4 x float>, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store <4 x float> zeroinitializer, <4 x float>* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(floatvec16, float __attribute__((vector_size(16))), { 3.1415926535897932384626433, 3.1415926535897932384626433, 3.1415926535897932384626433, 3.1415926535897932384626433 });
+// CHECK-LABEL: @test_floatvec16_custom()
+// CHECK: %custom = alloca <4 x float>, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store <4 x float> <float 0x400921FB60000000, float 0x400921FB60000000, float 0x400921FB60000000, float 0x400921FB60000000>, <4 x float>* %custom, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(doublevec32, double __attribute__((vector_size(32))));
+// CHECK-LABEL: @test_doublevec32_uninit()
+// CHECK: %uninit = alloca <4 x double>, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_doublevec32_uninit()
+// PATTERN: store <4 x double> <double 0xFFFFFFFFFFFFFFFF, double 0xFFFFFFFFFFFFFFFF, double 0xFFFFFFFFFFFFFFFF, double 0xFFFFFFFFFFFFFFFF>, <4 x double>* %uninit, align 32
+// ZERO-LABEL: @test_doublevec32_uninit()
+// ZERO: store <4 x double> zeroinitializer, <4 x double>* %uninit, align 32
+
+TEST_BRACES(doublevec32, double __attribute__((vector_size(32))));
+// CHECK-LABEL: @test_doublevec32_braces()
+// CHECK: %braces = alloca <4 x double>, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store <4 x double> zeroinitializer, <4 x double>* %braces, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(doublevec32, double __attribute__((vector_size(32))), { 3.1415926535897932384626433, 3.1415926535897932384626433, 3.1415926535897932384626433, 3.1415926535897932384626433 });
+// CHECK-LABEL: @test_doublevec32_custom()
+// CHECK: %custom = alloca <4 x double>, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: store <4 x double> <double 0x400921FB54442D18, double 0x400921FB54442D18, double 0x400921FB54442D18, double 0x400921FB54442D18>, <4 x double>* %custom, align [[ALIGN]]
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+
+} // extern "C"
diff --git a/src/llvm-project/clang/test/CodeGenCXX/auto-variable-template.cpp b/src/llvm-project/clang/test/CodeGenCXX/auto-variable-template.cpp
new file mode 100644
index 0000000..265d81d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/auto-variable-template.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -std=c++14 %s -triple=x86_64-linux -emit-llvm -o - | FileCheck %s
+
+struct f {
+ void operator()() const {}
+};
+
+template <typename T> auto vtemplate = f{};
+
+int main() { vtemplate<int>(); }
+
+// CHECK: @_Z9vtemplateIiE = linkonce_odr global %struct.f undef, comdat
+
+// CHECK: define i32 @main()
+// CHECK: call void @_ZNK1fclEv(%struct.f* @_Z9vtemplateIiE)
diff --git a/src/llvm-project/clang/test/CodeGenCXX/bitfield-layout.cpp b/src/llvm-project/clang/test/CodeGenCXX/bitfield-layout.cpp
new file mode 100644
index 0000000..46f4111
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/bitfield-layout.cpp
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - -O3 | FileCheck -check-prefix CHECK-LP64 %s
+// RUN: %clang_cc1 %s -triple=i386-apple-darwin10 -emit-llvm -o - -O3 | FileCheck -check-prefix CHECK-LP32 %s
+
+// CHECK-LP64: %union.Test1 = type { i32, [4 x i8] }
+union Test1 {
+ int a;
+ int b: 39;
+} t1;
+
+// CHECK-LP64: %union.Test2 = type { i8 }
+union Test2 {
+ int : 6;
+} t2;
+
+// CHECK-LP64: %union.Test3 = type { i16 }
+union Test3 {
+ int : 9;
+} t3;
+
+
+#define CHECK(x) if (!(x)) return __LINE__
+
+int f() {
+ struct {
+ int a;
+
+ unsigned long long b : 65;
+
+ int c;
+ } c;
+
+ c.a = 0;
+ c.b = (unsigned long long)-1;
+ c.c = 0;
+
+ CHECK(c.a == 0);
+ CHECK(c.b == (unsigned long long)-1);
+ CHECK(c.c == 0);
+
+// CHECK-LP64: ret i32 0
+// CHECK-LP32: ret i32 0
+ return 0;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/bitfield.cpp b/src/llvm-project/clang/test/CodeGenCXX/bitfield.cpp
new file mode 100644
index 0000000..7f55b4d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/bitfield.cpp
@@ -0,0 +1,480 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s \
+// RUN: | FileCheck -check-prefix=CHECK-X86-64 %s
+// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -emit-llvm -o - %s \
+// RUN: | FileCheck -check-prefix=CHECK-PPC64 %s
+//
+// Tests for bitfield access patterns in C++ with special attention to
+// conformance to C++11 memory model requirements.
+
+namespace N0 {
+ // Test basic bitfield layout access across interesting byte and word
+ // boundaries on both little endian and big endian platforms.
+ struct __attribute__((packed)) S {
+ unsigned b00 : 14;
+ unsigned b01 : 2;
+ unsigned b20 : 6;
+ unsigned b21 : 2;
+ unsigned b30 : 30;
+ unsigned b31 : 2;
+ unsigned b70 : 6;
+ unsigned b71 : 2;
+ };
+ unsigned read00(S* s) {
+ // CHECK-X86-64-LABEL: define i32 @_ZN2N06read00
+ // CHECK-X86-64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i64*
+ // CHECK-X86-64: %[[val:.*]] = load i64, i64* %[[ptr]]
+ // CHECK-X86-64: %[[and:.*]] = and i64 %[[val]], 16383
+ // CHECK-X86-64: %[[trunc:.*]] = trunc i64 %[[and]] to i32
+ // CHECK-X86-64: ret i32 %[[trunc]]
+ // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N06read00
+ // CHECK-PPC64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i64*
+ // CHECK-PPC64: %[[val:.*]] = load i64, i64* %[[ptr]]
+ // CHECK-PPC64: %[[shr:.*]] = lshr i64 %[[val]], 50
+ // CHECK-PPC64: %[[trunc:.*]] = trunc i64 %[[shr]] to i32
+ // CHECK-PPC64: ret i32 %[[trunc]]
+ return s->b00;
+ }
+ unsigned read01(S* s) {
+ // CHECK-X86-64-LABEL: define i32 @_ZN2N06read01
+ // CHECK-X86-64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i64*
+ // CHECK-X86-64: %[[val:.*]] = load i64, i64* %[[ptr]]
+ // CHECK-X86-64: %[[shr:.*]] = lshr i64 %[[val]], 14
+ // CHECK-X86-64: %[[and:.*]] = and i64 %[[shr]], 3
+ // CHECK-X86-64: %[[trunc:.*]] = trunc i64 %[[and]] to i32
+ // CHECK-X86-64: ret i32 %[[trunc]]
+ // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N06read01
+ // CHECK-PPC64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i64*
+ // CHECK-PPC64: %[[val:.*]] = load i64, i64* %[[ptr]]
+ // CHECK-PPC64: %[[shr:.*]] = lshr i64 %[[val]], 48
+ // CHECK-PPC64: %[[and:.*]] = and i64 %[[shr]], 3
+ // CHECK-PPC64: %[[trunc:.*]] = trunc i64 %[[and]] to i32
+ // CHECK-PPC64: ret i32 %[[trunc]]
+ return s->b01;
+ }
+ unsigned read20(S* s) {
+ // CHECK-X86-64-LABEL: define i32 @_ZN2N06read20
+ // CHECK-X86-64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i64*
+ // CHECK-X86-64: %[[val:.*]] = load i64, i64* %[[ptr]]
+ // CHECK-X86-64: %[[shr:.*]] = lshr i64 %[[val]], 16
+ // CHECK-X86-64: %[[and:.*]] = and i64 %[[shr]], 63
+ // CHECK-X86-64: %[[trunc:.*]] = trunc i64 %[[and]] to i32
+ // CHECK-X86-64: ret i32 %[[trunc]]
+ // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N06read20
+ // CHECK-PPC64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i64*
+ // CHECK-PPC64: %[[val:.*]] = load i64, i64* %[[ptr]]
+ // CHECK-PPC64: %[[shr:.*]] = lshr i64 %[[val]], 42
+ // CHECK-PPC64: %[[and:.*]] = and i64 %[[shr]], 63
+ // CHECK-PPC64: %[[trunc:.*]] = trunc i64 %[[and]] to i32
+ // CHECK-PPC64: ret i32 %[[trunc]]
+ return s->b20;
+ }
+ unsigned read21(S* s) {
+ // CHECK-X86-64-LABEL: define i32 @_ZN2N06read21
+ // CHECK-X86-64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i64*
+ // CHECK-X86-64: %[[val:.*]] = load i64, i64* %[[ptr]]
+ // CHECK-X86-64: %[[shr:.*]] = lshr i64 %[[val]], 22
+ // CHECK-X86-64: %[[and:.*]] = and i64 %[[shr]], 3
+ // CHECK-X86-64: %[[trunc:.*]] = trunc i64 %[[and]] to i32
+ // CHECK-X86-64: ret i32 %[[trunc]]
+ // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N06read21
+ // CHECK-PPC64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i64*
+ // CHECK-PPC64: %[[val:.*]] = load i64, i64* %[[ptr]]
+ // CHECK-PPC64: %[[shr:.*]] = lshr i64 %[[val]], 40
+ // CHECK-PPC64: %[[and:.*]] = and i64 %[[shr]], 3
+ // CHECK-PPC64: %[[trunc:.*]] = trunc i64 %[[and]] to i32
+ // CHECK-PPC64: ret i32 %[[trunc]]
+ return s->b21;
+ }
+ unsigned read30(S* s) {
+ // CHECK-X86-64-LABEL: define i32 @_ZN2N06read30
+ // CHECK-X86-64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i64*
+ // CHECK-X86-64: %[[val:.*]] = load i64, i64* %[[ptr]]
+ // CHECK-X86-64: %[[shr:.*]] = lshr i64 %[[val]], 24
+ // CHECK-X86-64: %[[and:.*]] = and i64 %[[shr]], 1073741823
+ // CHECK-X86-64: %[[trunc:.*]] = trunc i64 %[[and]] to i32
+ // CHECK-X86-64: ret i32 %[[trunc]]
+ // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N06read30
+ // CHECK-PPC64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i64*
+ // CHECK-PPC64: %[[val:.*]] = load i64, i64* %[[ptr]]
+ // CHECK-PPC64: %[[shr:.*]] = lshr i64 %[[val]], 10
+ // CHECK-PPC64: %[[and:.*]] = and i64 %[[shr]], 1073741823
+ // CHECK-PPC64: %[[trunc:.*]] = trunc i64 %[[and]] to i32
+ // CHECK-PPC64: ret i32 %[[trunc]]
+ return s->b30;
+ }
+ unsigned read31(S* s) {
+ // CHECK-X86-64-LABEL: define i32 @_ZN2N06read31
+ // CHECK-X86-64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i64*
+ // CHECK-X86-64: %[[val:.*]] = load i64, i64* %[[ptr]]
+ // CHECK-X86-64: %[[shr:.*]] = lshr i64 %[[val]], 54
+ // CHECK-X86-64: %[[and:.*]] = and i64 %[[shr]], 3
+ // CHECK-X86-64: %[[trunc:.*]] = trunc i64 %[[and]] to i32
+ // CHECK-X86-64: ret i32 %[[trunc]]
+ // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N06read31
+ // CHECK-PPC64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i64*
+ // CHECK-PPC64: %[[val:.*]] = load i64, i64* %[[ptr]]
+ // CHECK-PPC64: %[[shr:.*]] = lshr i64 %[[val]], 8
+ // CHECK-PPC64: %[[and:.*]] = and i64 %[[shr]], 3
+ // CHECK-PPC64: %[[trunc:.*]] = trunc i64 %[[and]] to i32
+ // CHECK-PPC64: ret i32 %[[trunc]]
+ return s->b31;
+ }
+ unsigned read70(S* s) {
+ // CHECK-X86-64-LABEL: define i32 @_ZN2N06read70
+ // CHECK-X86-64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i64*
+ // CHECK-X86-64: %[[val:.*]] = load i64, i64* %[[ptr]]
+ // CHECK-X86-64: %[[shr:.*]] = lshr i64 %[[val]], 56
+ // CHECK-X86-64: %[[and:.*]] = and i64 %[[shr]], 63
+ // CHECK-X86-64: %[[trunc:.*]] = trunc i64 %[[and]] to i32
+ // CHECK-X86-64: ret i32 %[[trunc]]
+ // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N06read70
+ // CHECK-PPC64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i64*
+ // CHECK-PPC64: %[[val:.*]] = load i64, i64* %[[ptr]]
+ // CHECK-PPC64: %[[shr:.*]] = lshr i64 %[[val]], 2
+ // CHECK-PPC64: %[[and:.*]] = and i64 %[[shr]], 63
+ // CHECK-PPC64: %[[trunc:.*]] = trunc i64 %[[and]] to i32
+ // CHECK-PPC64: ret i32 %[[trunc]]
+ return s->b70;
+ }
+ unsigned read71(S* s) {
+ // CHECK-X86-64-LABEL: define i32 @_ZN2N06read71
+ // CHECK-X86-64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i64*
+ // CHECK-X86-64: %[[val:.*]] = load i64, i64* %[[ptr]]
+ // CHECK-X86-64: %[[shr:.*]] = lshr i64 %[[val]], 62
+ // CHECK-X86-64: %[[trunc:.*]] = trunc i64 %[[shr]] to i32
+ // CHECK-X86-64: ret i32 %[[trunc]]
+ // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N06read71
+ // CHECK-PPC64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i64*
+ // CHECK-PPC64: %[[val:.*]] = load i64, i64* %[[ptr]]
+ // CHECK-PPC64: %[[and:.*]] = and i64 %[[val]], 3
+ // CHECK-PPC64: %[[trunc:.*]] = trunc i64 %[[and]] to i32
+ // CHECK-PPC64: ret i32 %[[trunc]]
+ return s->b71;
+ }
+}
+
+namespace N1 {
+ // Ensure that neither loads nor stores to bitfields are not widened into
+ // other memory locations. (PR13691)
+ //
+ // NOTE: We could potentially widen loads based on their alignment if we are
+ // comfortable requiring that subsequent memory locations within the
+ // alignment-widened load are not volatile.
+ struct S {
+ char a;
+ unsigned b : 1;
+ char c;
+ };
+ unsigned read(S* s) {
+ // CHECK-X86-64-LABEL: define i32 @_ZN2N14read
+ // CHECK-X86-64: %[[ptr:.*]] = getelementptr inbounds %{{.*}}, %{{.*}}* %{{.*}}, i32 0, i32 1
+ // CHECK-X86-64: %[[val:.*]] = load i8, i8* %[[ptr]]
+ // CHECK-X86-64: %[[and:.*]] = and i8 %[[val]], 1
+ // CHECK-X86-64: %[[ext:.*]] = zext i8 %[[and]] to i32
+ // CHECK-X86-64: ret i32 %[[ext]]
+ // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N14read
+ // CHECK-PPC64: %[[ptr:.*]] = getelementptr inbounds %{{.*}}, %{{.*}}* %{{.*}}, i32 0, i32 1
+ // CHECK-PPC64: %[[val:.*]] = load i8, i8* %[[ptr]]
+ // CHECK-PPC64: %[[shr:.*]] = lshr i8 %[[val]], 7
+ // CHECK-PPC64: %[[ext:.*]] = zext i8 %[[shr]] to i32
+ // CHECK-PPC64: ret i32 %[[ext]]
+ return s->b;
+ }
+ void write(S* s, unsigned x) {
+ // CHECK-X86-64-LABEL: define void @_ZN2N15write
+ // CHECK-X86-64: %[[ptr:.*]] = getelementptr inbounds %{{.*}}, %{{.*}}* %{{.*}}, i32 0, i32 1
+ // CHECK-X86-64: %[[x_trunc:.*]] = trunc i32 %{{.*}} to i8
+ // CHECK-X86-64: %[[old:.*]] = load i8, i8* %[[ptr]]
+ // CHECK-X86-64: %[[x_and:.*]] = and i8 %[[x_trunc]], 1
+ // CHECK-X86-64: %[[old_and:.*]] = and i8 %[[old]], -2
+ // CHECK-X86-64: %[[new:.*]] = or i8 %[[old_and]], %[[x_and]]
+ // CHECK-X86-64: store i8 %[[new]], i8* %[[ptr]]
+ // CHECK-PPC64-LABEL: define void @_ZN2N15write
+ // CHECK-PPC64: %[[ptr:.*]] = getelementptr inbounds %{{.*}}, %{{.*}}* %{{.*}}, i32 0, i32 1
+ // CHECK-PPC64: %[[x_trunc:.*]] = trunc i32 %{{.*}} to i8
+ // CHECK-PPC64: %[[old:.*]] = load i8, i8* %[[ptr]]
+ // CHECK-PPC64: %[[x_and:.*]] = and i8 %[[x_trunc]], 1
+ // CHECK-PPC64: %[[x_shl:.*]] = shl i8 %[[x_and]], 7
+ // CHECK-PPC64: %[[old_and:.*]] = and i8 %[[old]], 127
+ // CHECK-PPC64: %[[new:.*]] = or i8 %[[old_and]], %[[x_shl]]
+ // CHECK-PPC64: store i8 %[[new]], i8* %[[ptr]]
+ s->b = x;
+ }
+}
+
+namespace N2 {
+ // Do widen loads and stores to bitfields when those bitfields have padding
+ // within the struct following them.
+ struct S {
+ unsigned b : 24;
+ void *p;
+ };
+ unsigned read(S* s) {
+ // CHECK-X86-64-LABEL: define i32 @_ZN2N24read
+ // CHECK-X86-64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i32*
+ // CHECK-X86-64: %[[val:.*]] = load i32, i32* %[[ptr]]
+ // CHECK-X86-64: %[[and:.*]] = and i32 %[[val]], 16777215
+ // CHECK-X86-64: ret i32 %[[and]]
+ // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N24read
+ // CHECK-PPC64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i32*
+ // CHECK-PPC64: %[[val:.*]] = load i32, i32* %[[ptr]]
+ // CHECK-PPC64: %[[shr:.*]] = lshr i32 %[[val]], 8
+ // CHECK-PPC64: ret i32 %[[shr]]
+ return s->b;
+ }
+ void write(S* s, unsigned x) {
+ // CHECK-X86-64-LABEL: define void @_ZN2N25write
+ // CHECK-X86-64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i32*
+ // CHECK-X86-64: %[[old:.*]] = load i32, i32* %[[ptr]]
+ // CHECK-X86-64: %[[x_and:.*]] = and i32 %{{.*}}, 16777215
+ // CHECK-X86-64: %[[old_and:.*]] = and i32 %[[old]], -16777216
+ // CHECK-X86-64: %[[new:.*]] = or i32 %[[old_and]], %[[x_and]]
+ // CHECK-X86-64: store i32 %[[new]], i32* %[[ptr]]
+ // CHECK-PPC64-LABEL: define void @_ZN2N25write
+ // CHECK-PPC64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i32*
+ // CHECK-PPC64: %[[old:.*]] = load i32, i32* %[[ptr]]
+ // CHECK-PPC64: %[[x_and:.*]] = and i32 %{{.*}}, 16777215
+ // CHECK-PPC64: %[[x_shl:.*]] = shl i32 %[[x_and]], 8
+ // CHECK-PPC64: %[[old_and:.*]] = and i32 %[[old]], 255
+ // CHECK-PPC64: %[[new:.*]] = or i32 %[[old_and]], %[[x_shl]]
+ // CHECK-PPC64: store i32 %[[new]], i32* %[[ptr]]
+ s->b = x;
+ }
+}
+
+namespace N3 {
+ // Do widen loads and stores to bitfields through the trailing padding at the
+ // end of a struct.
+ struct S {
+ unsigned b : 24;
+ };
+ unsigned read(S* s) {
+ // CHECK-X86-64-LABEL: define i32 @_ZN2N34read
+ // CHECK-X86-64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i32*
+ // CHECK-X86-64: %[[val:.*]] = load i32, i32* %[[ptr]]
+ // CHECK-X86-64: %[[and:.*]] = and i32 %[[val]], 16777215
+ // CHECK-X86-64: ret i32 %[[and]]
+ // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N34read
+ // CHECK-PPC64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i32*
+ // CHECK-PPC64: %[[val:.*]] = load i32, i32* %[[ptr]]
+ // CHECK-PPC64: %[[shr:.*]] = lshr i32 %[[val]], 8
+ // CHECK-PPC64: ret i32 %[[shr]]
+ return s->b;
+ }
+ void write(S* s, unsigned x) {
+ // CHECK-X86-64-LABEL: define void @_ZN2N35write
+ // CHECK-X86-64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i32*
+ // CHECK-X86-64: %[[old:.*]] = load i32, i32* %[[ptr]]
+ // CHECK-X86-64: %[[x_and:.*]] = and i32 %{{.*}}, 16777215
+ // CHECK-X86-64: %[[old_and:.*]] = and i32 %[[old]], -16777216
+ // CHECK-X86-64: %[[new:.*]] = or i32 %[[old_and]], %[[x_and]]
+ // CHECK-X86-64: store i32 %[[new]], i32* %[[ptr]]
+ // CHECK-PPC64-LABEL: define void @_ZN2N35write
+ // CHECK-PPC64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i32*
+ // CHECK-PPC64: %[[old:.*]] = load i32, i32* %[[ptr]]
+ // CHECK-PPC64: %[[x_and:.*]] = and i32 %{{.*}}, 16777215
+ // CHECK-PPC64: %[[x_shl:.*]] = shl i32 %[[x_and]], 8
+ // CHECK-PPC64: %[[old_and:.*]] = and i32 %[[old]], 255
+ // CHECK-PPC64: %[[new:.*]] = or i32 %[[old_and]], %[[x_shl]]
+ // CHECK-PPC64: store i32 %[[new]], i32* %[[ptr]]
+ s->b = x;
+ }
+}
+
+namespace N4 {
+ // Do NOT widen loads and stores to bitfields into padding at the end of
+ // a class which might end up with members inside of it when inside a derived
+ // class.
+ struct Base {
+ virtual ~Base() {}
+
+ unsigned b : 24;
+ };
+ // Imagine some other translation unit introduces:
+#if 0
+ struct Derived : public Base {
+ char c;
+ };
+#endif
+ unsigned read(Base* s) {
+ // FIXME: We should widen this load as long as the function isn't being
+ // instrumented by ThreadSanitizer.
+ //
+ // CHECK-X86-64-LABEL: define i32 @_ZN2N44read
+ // CHECK-X86-64: %[[gep:.*]] = getelementptr inbounds {{.*}}, {{.*}}* %{{.*}}, i32 0, i32 1
+ // CHECK-X86-64: %[[ptr:.*]] = bitcast [3 x i8]* %[[gep]] to i24*
+ // CHECK-X86-64: %[[val:.*]] = load i24, i24* %[[ptr]]
+ // CHECK-X86-64: %[[ext:.*]] = zext i24 %[[val]] to i32
+ // CHECK-X86-64: ret i32 %[[ext]]
+ // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N44read
+ // CHECK-PPC64: %[[gep:.*]] = getelementptr inbounds {{.*}}, {{.*}}* %{{.*}}, i32 0, i32 1
+ // CHECK-PPC64: %[[ptr:.*]] = bitcast [3 x i8]* %[[gep]] to i24*
+ // CHECK-PPC64: %[[val:.*]] = load i24, i24* %[[ptr]]
+ // CHECK-PPC64: %[[ext:.*]] = zext i24 %[[val]] to i32
+ // CHECK-PPC64: ret i32 %[[ext]]
+ return s->b;
+ }
+ void write(Base* s, unsigned x) {
+ // CHECK-X86-64-LABEL: define void @_ZN2N45write
+ // CHECK-X86-64: %[[gep:.*]] = getelementptr inbounds {{.*}}, {{.*}}* %{{.*}}, i32 0, i32 1
+ // CHECK-X86-64: %[[ptr:.*]] = bitcast [3 x i8]* %[[gep]] to i24*
+ // CHECK-X86-64: %[[new:.*]] = trunc i32 %{{.*}} to i24
+ // CHECK-X86-64: store i24 %[[new]], i24* %[[ptr]]
+ // CHECK-PPC64-LABEL: define void @_ZN2N45write
+ // CHECK-PPC64: %[[gep:.*]] = getelementptr inbounds {{.*}}, {{.*}}* %{{.*}}, i32 0, i32 1
+ // CHECK-PPC64: %[[ptr:.*]] = bitcast [3 x i8]* %[[gep]] to i24*
+ // CHECK-PPC64: %[[new:.*]] = trunc i32 %{{.*}} to i24
+ // CHECK-PPC64: store i24 %[[new]], i24* %[[ptr]]
+ s->b = x;
+ }
+}
+
+namespace N5 {
+ // Widen through padding at the end of a struct even if that struct
+ // participates in a union with another struct which has a separate field in
+ // that location. The reasoning is that if the operation is storing to that
+ // member of the union, it must be the active member, and thus we can write
+ // through the padding. If it is a load, it might be a load of a common
+ // prefix through a non-active member, but in such a case the extra bits
+ // loaded are masked off anyways.
+ union U {
+ struct X { unsigned b : 24; char c; } x;
+ struct Y { unsigned b : 24; } y;
+ };
+ unsigned read(U* u) {
+ // CHECK-X86-64-LABEL: define i32 @_ZN2N54read
+ // CHECK-X86-64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i32*
+ // CHECK-X86-64: %[[val:.*]] = load i32, i32* %[[ptr]]
+ // CHECK-X86-64: %[[and:.*]] = and i32 %[[val]], 16777215
+ // CHECK-X86-64: ret i32 %[[and]]
+ // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N54read
+ // CHECK-PPC64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i32*
+ // CHECK-PPC64: %[[val:.*]] = load i32, i32* %[[ptr]]
+ // CHECK-PPC64: %[[shr:.*]] = lshr i32 %[[val]], 8
+ // CHECK-PPC64: ret i32 %[[shr]]
+ return u->y.b;
+ }
+ void write(U* u, unsigned x) {
+ // CHECK-X86-64-LABEL: define void @_ZN2N55write
+ // CHECK-X86-64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i32*
+ // CHECK-X86-64: %[[old:.*]] = load i32, i32* %[[ptr]]
+ // CHECK-X86-64: %[[x_and:.*]] = and i32 %{{.*}}, 16777215
+ // CHECK-X86-64: %[[old_and:.*]] = and i32 %[[old]], -16777216
+ // CHECK-X86-64: %[[new:.*]] = or i32 %[[old_and]], %[[x_and]]
+ // CHECK-X86-64: store i32 %[[new]], i32* %[[ptr]]
+ // CHECK-PPC64-LABEL: define void @_ZN2N55write
+ // CHECK-PPC64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i32*
+ // CHECK-PPC64: %[[old:.*]] = load i32, i32* %[[ptr]]
+ // CHECK-PPC64: %[[x_and:.*]] = and i32 %{{.*}}, 16777215
+ // CHECK-PPC64: %[[x_shl:.*]] = shl i32 %[[x_and]], 8
+ // CHECK-PPC64: %[[old_and:.*]] = and i32 %[[old]], 255
+ // CHECK-PPC64: %[[new:.*]] = or i32 %[[old_and]], %[[x_shl]]
+ // CHECK-PPC64: store i32 %[[new]], i32* %[[ptr]]
+ u->y.b = x;
+ }
+}
+
+namespace N6 {
+ // Zero-length bitfields partition the memory locations of bitfields for the
+ // purposes of the memory model. That means stores must not span zero-length
+ // bitfields and loads may only span them when we are not instrumenting with
+ // ThreadSanitizer.
+ // FIXME: We currently don't widen loads even without ThreadSanitizer, even
+ // though we could.
+ struct S {
+ unsigned b1 : 24;
+ unsigned char : 0;
+ unsigned char b2 : 8;
+ };
+ unsigned read(S* s) {
+ // CHECK-X86-64-LABEL: define i32 @_ZN2N64read
+ // CHECK-X86-64: %[[ptr1:.*]] = bitcast {{.*}}* %{{.*}} to i24*
+ // CHECK-X86-64: %[[val1:.*]] = load i24, i24* %[[ptr1]]
+ // CHECK-X86-64: %[[ext1:.*]] = zext i24 %[[val1]] to i32
+ // CHECK-X86-64: %[[ptr2:.*]] = getelementptr inbounds {{.*}}, {{.*}}* %{{.*}}, i32 0, i32 1
+ // CHECK-X86-64: %[[val2:.*]] = load i8, i8* %[[ptr2]]
+ // CHECK-X86-64: %[[ext2:.*]] = zext i8 %[[val2]] to i32
+ // CHECK-X86-64: %[[add:.*]] = add nsw i32 %[[ext1]], %[[ext2]]
+ // CHECK-X86-64: ret i32 %[[add]]
+ // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N64read
+ // CHECK-PPC64: %[[ptr1:.*]] = bitcast {{.*}}* %{{.*}} to i24*
+ // CHECK-PPC64: %[[val1:.*]] = load i24, i24* %[[ptr1]]
+ // CHECK-PPC64: %[[ext1:.*]] = zext i24 %[[val1]] to i32
+ // CHECK-PPC64: %[[ptr2:.*]] = getelementptr inbounds {{.*}}, {{.*}}* %{{.*}}, i32 0, i32 1
+ // CHECK-PPC64: %[[val2:.*]] = load i8, i8* %[[ptr2]]
+ // CHECK-PPC64: %[[ext2:.*]] = zext i8 %[[val2]] to i32
+ // CHECK-PPC64: %[[add:.*]] = add nsw i32 %[[ext1]], %[[ext2]]
+ // CHECK-PPC64: ret i32 %[[add]]
+ return s->b1 + s->b2;
+ }
+ void write(S* s, unsigned x) {
+ // CHECK-X86-64-LABEL: define void @_ZN2N65write
+ // CHECK-X86-64: %[[ptr1:.*]] = bitcast {{.*}}* %{{.*}} to i24*
+ // CHECK-X86-64: %[[new1:.*]] = trunc i32 %{{.*}} to i24
+ // CHECK-X86-64: store i24 %[[new1]], i24* %[[ptr1]]
+ // CHECK-X86-64: %[[new2:.*]] = trunc i32 %{{.*}} to i8
+ // CHECK-X86-64: %[[ptr2:.*]] = getelementptr inbounds {{.*}}, {{.*}}* %{{.*}}, i32 0, i32 1
+ // CHECK-X86-64: store i8 %[[new2]], i8* %[[ptr2]]
+ // CHECK-PPC64-LABEL: define void @_ZN2N65write
+ // CHECK-PPC64: %[[ptr1:.*]] = bitcast {{.*}}* %{{.*}} to i24*
+ // CHECK-PPC64: %[[new1:.*]] = trunc i32 %{{.*}} to i24
+ // CHECK-PPC64: store i24 %[[new1]], i24* %[[ptr1]]
+ // CHECK-PPC64: %[[new2:.*]] = trunc i32 %{{.*}} to i8
+ // CHECK-PPC64: %[[ptr2:.*]] = getelementptr inbounds {{.*}}, {{.*}}* %{{.*}}, i32 0, i32 1
+ // CHECK-PPC64: store i8 %[[new2]], i8* %[[ptr2]]
+ s->b1 = x;
+ s->b2 = x;
+ }
+}
+
+namespace N7 {
+ // Similar to N4 except that this adds a virtual base to the picture. (PR18430)
+ // Do NOT widen loads and stores to bitfields into padding at the end of
+ // a class which might end up with members inside of it when inside a derived
+ // class.
+ struct B1 {
+ virtual void f();
+ unsigned b1 : 24;
+ };
+ struct B2 : virtual B1 {
+ virtual ~B2();
+ unsigned b : 24;
+ };
+ // Imagine some other translation unit introduces:
+#if 0
+ struct Derived : public B2 {
+ char c;
+ };
+#endif
+ unsigned read(B2* s) {
+ // FIXME: We should widen this load as long as the function isn't being
+ // instrumented by ThreadSanitizer.
+ //
+ // CHECK-X86-64-LABEL: define i32 @_ZN2N74read
+ // CHECK-X86-64: %[[gep:.*]] = getelementptr inbounds {{.*}}, {{.*}}* %{{.*}}, i32 0, i32 1
+ // CHECK-X86-64: %[[ptr:.*]] = bitcast [3 x i8]* %[[gep]] to i24*
+ // CHECK-X86-64: %[[val:.*]] = load i24, i24* %[[ptr]]
+ // CHECK-X86-64: %[[ext:.*]] = zext i24 %[[val]] to i32
+ // CHECK-X86-64: ret i32 %[[ext]]
+ // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N74read
+ // CHECK-PPC64: %[[gep:.*]] = getelementptr inbounds {{.*}}, {{.*}}* %{{.*}}, i32 0, i32 1
+ // CHECK-PPC64: %[[ptr:.*]] = bitcast [3 x i8]* %[[gep]] to i24*
+ // CHECK-PPC64: %[[val:.*]] = load i24, i24* %[[ptr]]
+ // CHECK-PPC64: %[[ext:.*]] = zext i24 %[[val]] to i32
+ // CHECK-PPC64: ret i32 %[[ext]]
+ return s->b;
+ }
+ void write(B2* s, unsigned x) {
+ // CHECK-X86-64-LABEL: define void @_ZN2N75write
+ // CHECK-X86-64: %[[gep:.*]] = getelementptr inbounds {{.*}}, {{.*}}* %{{.*}}, i32 0, i32 1
+ // CHECK-X86-64: %[[ptr:.*]] = bitcast [3 x i8]* %[[gep]] to i24*
+ // CHECK-X86-64: %[[new:.*]] = trunc i32 %{{.*}} to i24
+ // CHECK-X86-64: store i24 %[[new]], i24* %[[ptr]]
+ // CHECK-PPC64-LABEL: define void @_ZN2N75write
+ // CHECK-PPC64: %[[gep:.*]] = getelementptr inbounds {{.*}}, {{.*}}* %{{.*}}, i32 0, i32 1
+ // CHECK-PPC64: %[[ptr:.*]] = bitcast [3 x i8]* %[[gep]] to i24*
+ // CHECK-PPC64: %[[new:.*]] = trunc i32 %{{.*}} to i24
+ // CHECK-PPC64: store i24 %[[new]], i24* %[[ptr]]
+ s->b = x;
+ }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/block-byref-cxx-objc.cpp b/src/llvm-project/clang/test/CodeGenCXX/block-byref-cxx-objc.cpp
new file mode 100644
index 0000000..6aca809
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/block-byref-cxx-objc.cpp
@@ -0,0 +1,63 @@
+// RUN: %clang_cc1 %s -std=c++11 -emit-llvm -triple %itanium_abi_triple -o - -fblocks -fexceptions | FileCheck %s
+// rdar://8594790
+
+struct A {
+ int x;
+ A(const A &);
+ A();
+ ~A() noexcept(false);
+};
+
+struct B {
+ int x;
+ B(const B &);
+ B();
+ ~B();
+};
+
+int testA() {
+ __block A a0, a1;
+ ^{ a0.x = 1234; a1.x = 5678; };
+ return 0;
+}
+
+// CHECK-LABEL: define internal void @__Block_byref_object_copy_
+// CHECK: call {{.*}} @_ZN1AC1ERKS_
+// CHECK-LABEL: define internal void @__Block_byref_object_dispose_
+// CHECK: call {{.*}} @_ZN1AD1Ev
+
+// CHECK-LABEL: define linkonce_odr hidden void @__copy_helper_block_e{{4|8}}_{{20|32}}rc{{24|40}}rc(
+// CHECK: call void @_Block_object_assign(
+// CHECK: invoke void @_Block_object_assign(
+// CHECK: call void @_Block_object_dispose({{.*}}) #[[NOUNWIND_ATTR:[0-9]+]]
+
+// CHECK-LABEL: define linkonce_odr hidden void @__destroy_helper_block_e{{4|8}}_{{20|32}}rd{{24|40}}rd(
+// CHECK: invoke void @_Block_object_dispose(
+// CHECK: call void @_Block_object_dispose(
+// CHECK: invoke void @_Block_object_dispose(
+
+int testB() {
+ __block B b0, b1;
+ ^{ b0.x = 1234; b1.x = 5678; };
+ return 0;
+}
+
+// CHECK-LABEL: define internal void @__Block_byref_object_copy_
+// CHECK: call {{.*}} @_ZN1BC1ERKS_
+// CHECK-LABEL: define internal void @__Block_byref_object_dispose_
+// CHECK: call {{.*}} @_ZN1BD1Ev
+
+// CHECK-NOT: define{{.*}}@__copy_helper_block
+// CHECK: define linkonce_odr hidden void @__destroy_helper_block_e{{4|8}}_{{20|32}}r{{24|40}}r(
+
+// CHECK: attributes #[[NOUNWIND_ATTR]] = {{{.*}}nounwind{{.*}}}
+
+// rdar://problem/11135650
+namespace test1 {
+ struct A { int x; A(); ~A(); };
+
+ void test() {
+ return;
+ __block A a;
+ }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/block-byref.cpp b/src/llvm-project/clang/test/CodeGenCXX/block-byref.cpp
new file mode 100644
index 0000000..1cb86a5
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/block-byref.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 %s -fblocks -triple x86_64-apple-darwin -std=c++11 -emit-llvm -o - | FileCheck %s
+// REQUIRES: x86-registered-target
+
+// CHECK: @b = global i32 0,
+
+// CHECK: define {{.*}}void @{{.*}}test{{.*}}_block_invoke(
+// CHECK: store i32 2, i32* @b,
+// CHECK: ret void
+
+int b;
+
+void test() {
+ int &a = b;
+ ^{ a = 2; };
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/block-capture.cpp b/src/llvm-project/clang/test/CodeGenCXX/block-capture.cpp
new file mode 100644
index 0000000..515d64d3
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/block-capture.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -x c++ -std=c++11 -fblocks -emit-llvm %s -o - | FileCheck %s
+
+// CHECK: %struct.__block_byref_baz = type { i8*, %struct.__block_byref_baz*, i32, i32, i32 }
+// CHECK: [[baz:%[0-9a-z_]*]] = alloca %struct.__block_byref_baz
+// CHECK: [[bazref:%[0-9a-z_\.]*]] = getelementptr inbounds %struct.__block_byref_baz, %struct.__block_byref_baz* [[baz]], i32 0, i32 1
+// CHECK: store %struct.__block_byref_baz* [[baz]], %struct.__block_byref_baz** [[bazref]]
+// CHECK: bitcast %struct.__block_byref_baz* [[baz]] to i8*
+// CHECK: [[disposable:%[0-9a-z_]*]] = bitcast %struct.__block_byref_baz* [[baz]] to i8*
+// CHECK: call void @_Block_object_dispose(i8* [[disposable]]
+
+int main() {
+ __block int baz = [&]() { return 0; }();
+ ^{ (void)baz; };
+ return 0;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/block-destruct.cpp b/src/llvm-project/clang/test/CodeGenCXX/block-destruct.cpp
new file mode 100644
index 0000000..f809ca2
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/block-destruct.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s -fblocks -triple x86_64-apple-darwin -emit-llvm -o - | FileCheck %s
+
+struct A { ~A(); };
+
+void f() {
+ __block A a;
+}
+
+// CHECK: call void @_ZN1AD1Ev
diff --git a/src/llvm-project/clang/test/CodeGenCXX/block-in-ctor-dtor.cpp b/src/llvm-project/clang/test/CodeGenCXX/block-in-ctor-dtor.cpp
new file mode 100644
index 0000000..0ec9db1
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/block-in-ctor-dtor.cpp
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 %s -fblocks -triple x86_64-apple-darwin -emit-llvm -o - | FileCheck %s
+
+typedef void (^dispatch_block_t)(void);
+
+void dispatch_once(dispatch_block_t);
+
+class Zone {
+public:
+ Zone();
+ ~Zone();
+};
+
+Zone::Zone() {
+ dispatch_once(^{});
+ dispatch_once(^{});
+}
+
+Zone::~Zone() {
+ dispatch_once(^{});
+ dispatch_once(^{});
+}
+
+class X : public virtual Zone {
+ X();
+ ~X();
+};
+
+X::X() {
+ dispatch_once(^{});
+ dispatch_once(^{});
+};
+
+X::~X() {
+ dispatch_once(^{});
+ dispatch_once(^{});
+};
+
+
+// CHECK-LABEL: define internal void @___ZN4ZoneC2Ev_block_invoke
+// CHECK-LABEL: define internal void @___ZN4ZoneC2Ev_block_invoke_
+// CHECK-LABEL: define internal void @___ZN4ZoneD2Ev_block_invoke
+// CHECK-LABEL: define internal void @___ZN4ZoneD2Ev_block_invoke_
+// CHECK-LABEL: define internal void @___ZN1XC2Ev_block_invoke
+// CHECK-LABEL: define internal void @___ZN1XC2Ev_block_invoke_
+// CHECK-LABEL: define internal void @___ZN1XD2Ev_block_invoke
+// CHECK-LABEL: define internal void @___ZN1XD2Ev_block_invoke_
diff --git a/src/llvm-project/clang/test/CodeGenCXX/block-inalloca.cpp b/src/llvm-project/clang/test/CodeGenCXX/block-inalloca.cpp
new file mode 100644
index 0000000..b827dde
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/block-inalloca.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -triple i686-unknown-windows-msvc -fblocks -emit-llvm -o - %s | FileCheck %s
+
+struct S {
+ S(const struct S &) {}
+};
+
+void (^b)(S) = ^(S) {};
+
+// CHECK: [[DESCRIPTOR:%.*]] = getelementptr inbounds <{ i8*, %struct.S, [3 x i8] }>, <{ i8*, %struct.S, [3 x i8] }>* %0, i32 0, i32 0
+// CHECK: load i8*, i8** [[DESCRIPTOR]]
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/block.cpp b/src/llvm-project/clang/test/CodeGenCXX/block.cpp
new file mode 100644
index 0000000..aa35668
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/block.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 %s -triple %itanium_abi_triple -emit-llvm -o - -fblocks
+// RUN: %clang_cc1 %s -triple %ms_abi_triple -fno-rtti -emit-llvm -o - -fblocks
+// Just test that this doesn't crash the compiler...
+
+void func(void*);
+
+struct Test
+{
+ virtual void use() { func((void*)this); }
+ Test(Test&c) { func((void*)this); }
+ Test() { func((void*)this); }
+};
+
+void useBlock(void (^)(void));
+
+int main (void) {
+ __block Test t;
+ useBlock(^(void) { t.use(); });
+}
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/blocks-cxx11.cpp b/src/llvm-project/clang/test/CodeGenCXX/blocks-cxx11.cpp
new file mode 100644
index 0000000..c437ad8
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/blocks-cxx11.cpp
@@ -0,0 +1,114 @@
+// RUN: %clang_cc1 %s -fblocks -triple x86_64-apple-darwin -std=c++11 -emit-llvm -o - | FileCheck %s
+
+template <class T> void takeItByValue(T);
+void takeABlock(void (^)());
+
+// rdar://problem/11022704
+namespace test_int {
+ void test() {
+ const int x = 100;
+ takeABlock(^{ takeItByValue(x); });
+ // CHECK: call void @_Z13takeItByValueIiEvT_(i32 100)
+ }
+}
+
+namespace test_int_ref {
+ void test() {
+ const int y = 200;
+ const int &x = y;
+ takeABlock(^{ takeItByValue(x); });
+
+ // TODO: there's no good reason that this isn't foldable.
+ // CHECK: call void @_Z13takeItByValueIiEvT_(i32 {{%.*}})
+ }
+}
+
+namespace test_float {
+ void test() {
+ const float x = 1;
+ takeABlock(^{ takeItByValue(x); });
+ // CHECK: call void @_Z13takeItByValueIfEvT_(float 1.0
+ }
+}
+
+namespace test_float_ref {
+ void test() {
+ const float y = 100;
+ const float &x = y;
+ takeABlock(^{ takeItByValue(x); });
+
+ // TODO: there's no good reason that this isn't foldable.
+ // CHECK: call void @_Z13takeItByValueIfEvT_(float {{%.*}})
+ }
+}
+
+namespace test_complex_int {
+ void test() {
+ constexpr _Complex int x = 500;
+ takeABlock(^{ takeItByValue(x); });
+ // CHECK: store { i32, i32 } { i32 500, i32 0 },
+
+ // CHECK: store i32 500,
+ // CHECK-NEXT: store i32 0,
+ // CHECK-NEXT: [[COERCE:%.*]] = bitcast
+ // CHECK-NEXT: [[CVAL:%.*]] = load i64, i64* [[COERCE]]
+ // CHECK-NEXT: call void @_Z13takeItByValueICiEvT_(i64 [[CVAL]])
+ }
+}
+
+namespace test_complex_int_ref {
+ void test() {
+ const _Complex int y = 100;
+ const _Complex int &x = y;
+ takeABlock(^{ takeItByValue(x); });
+ // CHECK: call void @_Z13takeItByValueICiEvT_(i64
+ }
+}
+
+namespace test_complex_int_ref_mutable {
+ _Complex int y = 100;
+ void test() {
+ const _Complex int &x = y;
+ takeABlock(^{ takeItByValue(x); });
+ // CHECK: [[R:%.*]] = load i32, i32* getelementptr inbounds ({ i32, i32 }, { i32, i32 }* @_ZN28test_complex_int_ref_mutable1yE, i32 0, i32 0)
+ // CHECK-NEXT: [[I:%.*]] = load i32, i32* getelementptr inbounds ({ i32, i32 }, { i32, i32 }* @_ZN28test_complex_int_ref_mutable1yE, i32 0, i32 1)
+ // CHECK-NEXT: [[RSLOT:%.*]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[CSLOT:%.*]], i32 0, i32 0
+ // CHECK-NEXT: [[ISLOT:%.*]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[CSLOT]], i32 0, i32 1
+ // CHECK-NEXT: store i32 [[R]], i32* [[RSLOT]]
+ // CHECK-NEXT: store i32 [[I]], i32* [[ISLOT]]
+ // CHECK-NEXT: [[COERCE:%.*]] = bitcast { i32, i32 }* [[CSLOT]] to i64*
+ // CHECK-NEXT: [[CVAL:%.*]] = load i64, i64* [[COERCE]],
+ // CHECK-NEXT: call void @_Z13takeItByValueICiEvT_(i64 [[CVAL]])
+ }
+}
+
+// rdar://13295759
+namespace test_block_in_lambda {
+ void takeBlock(void (^block)());
+
+ // The captured variable has to be non-POD so that we have a copy expression.
+ struct A {
+ void *p;
+ A(const A &);
+ ~A();
+ void use() const;
+ };
+
+ void test(A a) {
+ auto lambda = [a]() {
+ takeBlock(^{ a.use(); });
+ };
+ lambda(); // make sure we emit the invocation function
+ }
+ // CHECK-LABEL: define internal void @"_ZZN20test_block_in_lambda4testENS_1AEENK3$_0clEv"(
+ // CHECK: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]], align 8
+ // CHECK: [[THIS:%.*]] = load [[LAMBDA_T:%.*]]*, [[LAMBDA_T:%.*]]**
+ // CHECK: [[TO_DESTROY:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
+ // CHECK: [[T0:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
+ // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[LAMBDA_T]], [[LAMBDA_T]]* [[THIS]], i32 0, i32 0
+ // CHECK-NEXT: call void @_ZN20test_block_in_lambda1AC1ERKS0_({{.*}}* [[T0]], {{.*}}* dereferenceable({{[0-9]+}}) [[T1]])
+ // CHECK-NEXT: [[T0:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to void ()*
+ // CHECK-NEXT: call void @_ZN20test_block_in_lambda9takeBlockEU13block_pointerFvvE(void ()* [[T0]])
+ // CHECK-NEXT: call void @_ZN20test_block_in_lambda1AD1Ev({{.*}}* [[TO_DESTROY]])
+ // CHECK-NEXT: ret void
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/blocks.cpp b/src/llvm-project/clang/test/CodeGenCXX/blocks.cpp
new file mode 100644
index 0000000..3b3363d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/blocks.cpp
@@ -0,0 +1,309 @@
+// RUN: %clang_cc1 %s -fblocks -triple x86_64-apple-darwin -emit-llvm -o - | FileCheck %s
+
+// CHECK: %[[STRUCT_BLOCK_DESCRIPTOR:.*]] = type { i64, i64 }
+// CHECK: @[[BLOCK_DESCRIPTOR22:.*]] = internal constant { i64, i64, i8*, i8*, i8*, i8* } { i64 0, i64 36, i8* bitcast (void (i8*, i8*)* @__copy_helper_block_8_32c22_ZTSN12_GLOBAL__N_11BE to i8*), i8* bitcast (void (i8*)* @__destroy_helper_block_8_32c22_ZTSN12_GLOBAL__N_11BE to i8*), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @{{.*}}, i32 0, i32 0), i8* null }, align 8
+
+namespace test0 {
+ // CHECK-LABEL: define void @_ZN5test04testEi(
+ // CHECK: define internal void @___ZN5test04testEi_block_invoke{{.*}}(
+ // CHECK: define internal void @___ZN5test04testEi_block_invoke_2{{.*}}(
+ void test(int x) {
+ ^{ ^{ (void) x; }; };
+ }
+}
+
+extern void (^out)();
+
+namespace test1 {
+ // Capturing const objects doesn't require a local block.
+ // CHECK-LABEL: 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-LABEL: 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-LABEL: 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-LABEL: 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.
+}
+
+namespace test2 {
+ struct A {
+ A();
+ A(const A &);
+ ~A();
+ };
+
+ struct B {
+ B();
+ B(const B &);
+ ~B();
+ };
+
+ // CHECK-LABEL: define void @_ZN5test24testEv()
+ void test() {
+ __block A a;
+ __block B b;
+ ^{ (void)a; (void)b; };
+ }
+
+ // CHECK-LABEL: define internal void @__Block_byref_object_copy
+ // CHECK: call void @_ZN5test21AC1ERKS0_(
+
+ // CHECK-LABEL: define internal void @__Block_byref_object_dispose
+ // CHECK: call void @_ZN5test21AD1Ev(
+
+ // CHECK-LABEL: define internal void @__Block_byref_object_copy
+ // CHECK: call void @_ZN5test21BC1ERKS0_(
+
+ // CHECK-LABEL: define internal void @__Block_byref_object_dispose
+ // CHECK: call void @_ZN5test21BD1Ev(
+}
+
+// rdar://problem/9334739
+// Make sure we mark destructors for parameters captured in blocks.
+namespace test3 {
+ struct A {
+ A(const A&);
+ ~A();
+ };
+
+ struct B : A {
+ };
+
+ void test(B b) {
+ extern void consume(void(^)());
+ consume(^{ (void) b; });
+ }
+}
+
+// rdar://problem/9971485
+namespace test4 {
+ struct A {
+ A();
+ ~A();
+ };
+
+ void foo(A a);
+
+ void test() {
+ extern void consume(void(^)());
+ consume(^{ return foo(A()); });
+ }
+ // CHECK-LABEL: define void @_ZN5test44testEv()
+ // CHECK-LABEL: define internal void @___ZN5test44testEv_block_invoke
+ // CHECK: [[TMP:%.*]] = alloca [[A:%.*]], align 1
+ // CHECK-NEXT: store i8* [[BLOCKDESC:%.*]], i8** {{.*}}, align 8
+ // CHECK-NEXT: bitcast i8* [[BLOCKDESC]] to <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]* }>*
+ // CHECK: call void @_ZN5test41AC1Ev([[A]]* [[TMP]])
+ // CHECK-NEXT: call void @_ZN5test43fooENS_1AE([[A]]* [[TMP]])
+ // CHECK-NEXT: call void @_ZN5test41AD1Ev([[A]]* [[TMP]])
+ // CHECK-NEXT: ret void
+}
+
+namespace test5 {
+ struct A {
+ unsigned afield;
+ A();
+ A(const A&);
+ ~A();
+ void foo() const;
+ };
+
+ void doWithBlock(void(^)());
+
+ void test(bool cond) {
+ A x;
+ void (^b)() = (cond ? ^{ x.foo(); } : (void(^)()) 0);
+ doWithBlock(b);
+ }
+
+ // CHECK-LABEL: define void @_ZN5test54testEb(
+ // CHECK: [[COND:%.*]] = alloca i8
+ // CHECK-NEXT: [[X:%.*]] = alloca [[A:%.*]], align 4
+ // CHECK-NEXT: [[B:%.*]] = alloca void ()*, align 8
+ // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:.*]], align 8
+ // CHECK-NEXT: [[CLEANUP_ACTIVE:%.*]] = alloca i1
+ // CHECK-NEXT: [[T0:%.*]] = zext i1
+ // CHECK-NEXT: store i8 [[T0]], i8* [[COND]], align 1
+ // CHECK-NEXT: call void @_ZN5test51AC1Ev([[A]]* [[X]])
+ // CHECK-NEXT: [[CLEANUP_ADDR:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
+ // CHECK-NEXT: [[T0:%.*]] = load i8, i8* [[COND]], align 1
+ // CHECK-NEXT: [[T1:%.*]] = trunc i8 [[T0]] to i1
+ // CHECK-NEXT: store i1 false, i1* [[CLEANUP_ACTIVE]]
+ // CHECK-NEXT: br i1 [[T1]],
+
+ // CHECK-NOT: br
+ // CHECK: [[CAPTURE:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
+ // CHECK-NEXT: call void @_ZN5test51AC1ERKS0_([[A]]* [[CAPTURE]], [[A]]* dereferenceable({{[0-9]+}}) [[X]])
+ // CHECK-NEXT: store i1 true, i1* [[CLEANUP_ACTIVE]]
+ // CHECK-NEXT: bitcast [[BLOCK_T]]* [[BLOCK]] to void ()*
+ // CHECK-NEXT: br label
+ // CHECK: br label
+ // CHECK: phi
+ // CHECK-NEXT: store
+ // CHECK-NEXT: load
+ // CHECK-NEXT: call void @_ZN5test511doWithBlockEU13block_pointerFvvE(
+ // CHECK-NEXT: [[T0:%.*]] = load i1, i1* [[CLEANUP_ACTIVE]]
+ // CHECK-NEXT: br i1 [[T0]]
+ // CHECK: call void @_ZN5test51AD1Ev([[A]]* [[CLEANUP_ADDR]])
+ // CHECK-NEXT: br label
+ // CHECK: call void @_ZN5test51AD1Ev([[A]]* [[X]])
+ // CHECK-NEXT: ret void
+}
+
+namespace test6 {
+ struct A {
+ A();
+ ~A();
+ };
+
+ void foo(const A &, void (^)());
+ void bar();
+
+ void test() {
+ // Make sure that the temporary cleanup isn't somehow captured
+ // within the block.
+ foo(A(), ^{ bar(); });
+ bar();
+ }
+
+ // CHECK-LABEL: define void @_ZN5test64testEv()
+ // CHECK: [[TEMP:%.*]] = alloca [[A:%.*]], align 1
+ // CHECK-NEXT: call void @_ZN5test61AC1Ev([[A]]* [[TEMP]])
+ // CHECK-NEXT: call void @_ZN5test63fooERKNS_1AEU13block_pointerFvvE(
+ // CHECK-NEXT: call void @_ZN5test61AD1Ev([[A]]* [[TEMP]])
+ // CHECK-NEXT: call void @_ZN5test63barEv()
+ // CHECK-NEXT: ret void
+}
+
+namespace test7 {
+ int f() {
+ static int n;
+ int *const p = &n;
+ return ^{ return *p; }();
+ }
+}
+
+namespace test8 {
+ // <rdar://problem/10832617>: failure to capture this after skipping rebuild
+ // of the 'this' pointer.
+ struct X {
+ int x;
+
+ template<typename T>
+ int foo() {
+ return ^ { return x; }();
+ }
+ };
+
+ template int X::foo<int>();
+}
+
+// rdar://13459289
+namespace test9 {
+ struct B {
+ void *p;
+ B();
+ B(const B&);
+ ~B();
+ };
+
+ void use_block(void (^)());
+ void use_block_2(void (^)(), const B &a);
+
+ // Ensuring that creating a non-trivial capture copy expression
+ // doesn't end up stealing the block registration for the block we
+ // just parsed. That block must have captures or else it won't
+ // force registration. Must occur within a block for some reason.
+ void test() {
+ B x;
+ use_block(^{
+ int y;
+ use_block_2(^{ (void)y; }, x);
+ });
+ }
+}
+
+namespace test10 {
+ // Check that 'v' is included in the copy helper function name to indicate
+ // the constructor taking a volatile parameter is called to copy the captured
+ // object.
+
+ // CHECK-LABEL: define linkonce_odr hidden void @__copy_helper_block_8_32c16_ZTSVN6test101BE(
+ // CHECK: call void @_ZN6test101BC1ERVKS0_(
+ // CHECK-LABEL: define linkonce_odr hidden void @__destroy_helper_block_8_32c16_ZTSVN6test101BE(
+ // CHECK: call void @_ZN6test101BD1Ev(
+
+ struct B {
+ int a;
+ B();
+ B(const B &);
+ B(const volatile B &);
+ ~B();
+ };
+
+ void test() {
+ volatile B x;
+ ^{ (void)x; };
+ }
+}
+
+// Copy/dispose helper functions and block descriptors of blocks that capture
+// objects that are non-external and non-trivial have internal linkage.
+
+// CHECK-LABEL: define internal void @_ZN12_GLOBAL__N_14testEv(
+// CHECK: store %[[STRUCT_BLOCK_DESCRIPTOR]]* bitcast ({ i64, i64, i8*, i8*, i8*, i8* }* @[[BLOCK_DESCRIPTOR22]] to %[[STRUCT_BLOCK_DESCRIPTOR]]*), %[[STRUCT_BLOCK_DESCRIPTOR]]** %{{.*}}, align 8
+
+// CHECK-LABEL: define internal void @__copy_helper_block_8_32c22_ZTSN12_GLOBAL__N_11BE(
+// CHECK-LABEL: define internal void @__destroy_helper_block_8_32c22_ZTSN12_GLOBAL__N_11BE(
+
+namespace {
+ struct B {
+ int a;
+ B();
+ B(const B &);
+ ~B();
+ };
+
+ void test() {
+ B x;
+ ^{ (void)x; };
+ }
+}
+
+void callTest() {
+ test();
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/bool-bitfield.cpp b/src/llvm-project/clang/test/CodeGenCXX/bool-bitfield.cpp
new file mode 100644
index 0000000..a5a344f
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/bool-bitfield.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s \
+// RUN: | FileCheck %s
+
+// PR14638; make sure this doesn't crash.
+struct A {
+ bool m_sorted : 1;
+};
+void func1(bool b, A& a1)
+{
+ if ((a1.m_sorted = b)) {}
+}
+// CHECK-LABEL: define void @_Z5func1bR1A
+// CHECK: br i1
+// CHECK: ret void
diff --git a/src/llvm-project/clang/test/CodeGenCXX/builtin-constant-p.cpp b/src/llvm-project/clang/test/CodeGenCXX/builtin-constant-p.cpp
new file mode 100644
index 0000000..6d853e8
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/builtin-constant-p.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -triple=x86_64-linux-gnu -emit-llvm -o - %s
+
+// Don't crash if the argument to __builtin_constant_p isn't scalar.
+template <typename T>
+constexpr bool is_constant(const T v) {
+ return __builtin_constant_p(v);
+}
+
+template <typename T>
+class numeric {
+ public:
+ using type = T;
+
+ template <typename S>
+ constexpr numeric(S value)
+ : value_(static_cast<T>(value)) {}
+
+ private:
+ const T value_;
+};
+
+bool bcp() {
+ return is_constant(numeric<int>(1));
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/builtin-launder.cpp b/src/llvm-project/clang/test/CodeGenCXX/builtin-launder.cpp
new file mode 100644
index 0000000..b3d849c
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/builtin-launder.cpp
@@ -0,0 +1,321 @@
+// RUN: %clang_cc1 -triple=x86_64-linux-gnu -emit-llvm -fstrict-vtable-pointers -o - %s \
+// RUN: | FileCheck --check-prefixes=CHECK,CHECK-STRICT %s
+// RUN: %clang_cc1 -triple=x86_64-linux-gnu -emit-llvm -o - %s \
+// RUN: | FileCheck --check-prefixes=CHECK,CHECK-NONSTRICT %s
+
+//===----------------------------------------------------------------------===//
+// Positive Cases
+//===----------------------------------------------------------------------===//
+
+struct TestVirtualFn {
+ virtual void foo() {}
+};
+
+// CHECK-LABEL: define void @test_builtin_launder_virtual_fn
+extern "C" void test_builtin_launder_virtual_fn(TestVirtualFn *p) {
+ // CHECK: store [[TYPE:%[^ ]+]] %p, [[TYPE]]* %p.addr
+ // CHECK-NEXT: [[TMP0:%.*]] = load [[TYPE]], [[TYPE]]* %p.addr
+
+ // CHECK-NONSTRICT-NEXT: store [[TYPE]] [[TMP0]], [[TYPE]]* %d
+
+ // CHECK-STRICT-NEXT: [[TMP1:%.*]] = bitcast [[TYPE]] [[TMP0]] to i8*
+ // CHECK-STRICT-NEXT: [[TMP2:%.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* [[TMP1]])
+ // CHECK-STRICT-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP2]] to [[TYPE]]
+ // CHECK-STRICT-NEXT: store [[TYPE]] [[TMP3]], [[TYPE]]* %d
+
+ // CHECK-NEXT: ret void
+ TestVirtualFn *d = __builtin_launder(p);
+}
+
+struct TestPolyBase : TestVirtualFn {
+};
+
+// CHECK-LABEL: define void @test_builtin_launder_poly_base
+extern "C" void test_builtin_launder_poly_base(TestPolyBase *p) {
+ // CHECK-STRICT-NOT: ret void
+ // CHECK-STRICT: @llvm.launder.invariant.group
+
+ // CHECK-NONSTRICT-NOT: @llvm.launder.invariant.group
+
+ // CHECK: ret void
+ TestPolyBase *d = __builtin_launder(p);
+}
+
+struct TestBase {};
+struct TestVirtualBase : virtual TestBase {};
+
+// CHECK-LABEL: define void @test_builtin_launder_virtual_base
+extern "C" void test_builtin_launder_virtual_base(TestVirtualBase *p) {
+ // CHECK-STRICT-NOT: ret void
+ // CHECK-STRICT: @llvm.launder.invariant.group
+
+ // CHECK-NONSTRICT-NOT: @llvm.launder.invariant.group
+
+ // CHECK: ret void
+ TestVirtualBase *d = __builtin_launder(p);
+}
+
+//===----------------------------------------------------------------------===//
+// Negative Cases
+//===----------------------------------------------------------------------===//
+
+// CHECK-LABEL: define void @test_builtin_launder_ommitted_one
+extern "C" void test_builtin_launder_ommitted_one(int *p) {
+ // CHECK: entry
+ // CHECK-NEXT: %p.addr = alloca i32*
+ // CHECK-NEXT: %d = alloca i32*
+ // CHECK-NEXT: store i32* %p, i32** %p.addr, align 8
+ // CHECK-NEXT: [[TMP:%.*]] = load i32*, i32** %p.addr
+ // CHECK-NEXT: store i32* [[TMP]], i32** %d
+ // CHECK-NEXT: ret void
+ int *d = __builtin_launder(p);
+}
+
+struct TestNoInvariant {
+ int x;
+};
+
+// CHECK-LABEL: define void @test_builtin_launder_ommitted_two
+extern "C" void test_builtin_launder_ommitted_two(TestNoInvariant *p) {
+ // CHECK: entry
+ // CHECK-NOT: llvm.launder.invariant.group
+ // CHECK-NEXT: %p.addr = alloca [[TYPE:%.*]], align 8
+ // CHECK-NEXT: %d = alloca [[TYPE]]
+ // CHECK-NEXT: store [[TYPE]] %p, [[TYPE]]* %p.addr
+ // CHECK-NEXT: [[TMP:%.*]] = load [[TYPE]], [[TYPE]]* %p.addr
+ // CHECK-NEXT: store [[TYPE]] [[TMP]], [[TYPE]]* %d
+ // CHECK-NEXT: ret void
+ TestNoInvariant *d = __builtin_launder(p);
+}
+
+struct TestVirtualMember {
+ TestVirtualFn member;
+};
+
+// CHECK-LABEL: define void @test_builtin_launder_virtual_member
+extern "C" void test_builtin_launder_virtual_member(TestVirtualMember *p) {
+ // CHECK: entry
+ // CHECK-NONSTRICT-NOT: @llvm.launder.invariant.group
+ // CHECK-STRICT: @llvm.launder.invariant.group
+ // CHECK: ret void
+ TestVirtualMember *d = __builtin_launder(p);
+}
+
+struct TestVirtualMemberDepth2 {
+ TestVirtualMember member;
+};
+
+// CHECK-LABEL: define void @test_builtin_launder_virtual_member_depth_2
+extern "C" void test_builtin_launder_virtual_member_depth_2(TestVirtualMemberDepth2 *p) {
+ // CHECK: entry
+ // CHECK-NONSTRICT-NOT: @llvm.launder.invariant.group
+ // CHECK-STRICT: @llvm.launder.invariant.group
+ // CHECK: ret void
+ TestVirtualMemberDepth2 *d = __builtin_launder(p);
+}
+
+struct TestVirtualReferenceMember {
+ TestVirtualFn &member;
+};
+
+// CHECK-LABEL: define void @test_builtin_launder_virtual_reference_member
+extern "C" void test_builtin_launder_virtual_reference_member(TestVirtualReferenceMember *p) {
+ // CHECK: entry
+ // CHECK-NOT: @llvm.launder.invariant.group
+ // CHECK: ret void
+ TestVirtualReferenceMember *d = __builtin_launder(p);
+}
+
+struct TestRecursiveMember {
+ TestRecursiveMember() : member(*this) {}
+ TestRecursiveMember &member;
+};
+
+// CHECK-LABEL: define void @test_builtin_launder_recursive_member
+extern "C" void test_builtin_launder_recursive_member(TestRecursiveMember *p) {
+ // CHECK: entry
+ // CHECK-NOT: @llvm.launder.invariant.group
+ // CHECK: ret void
+ TestRecursiveMember *d = __builtin_launder(p);
+}
+
+struct TestVirtualRecursiveMember {
+ TestVirtualRecursiveMember() : member(*this) {}
+ TestVirtualRecursiveMember &member;
+ virtual void foo();
+};
+
+// CHECK-LABEL: define void @test_builtin_launder_virtual_recursive_member
+extern "C" void test_builtin_launder_virtual_recursive_member(TestVirtualRecursiveMember *p) {
+ // CHECK: entry
+ // CHECK-NONSTRICT-NOT: @llvm.launder.invariant.group
+ // CHECK-STRICT: @llvm.launder.invariant.group
+ // CHECK: ret void
+ TestVirtualRecursiveMember *d = __builtin_launder(p);
+}
+
+// CHECK-LABEL: define void @test_builtin_launder_array(
+extern "C" void test_builtin_launder_array(TestVirtualFn (&Arr)[5]) {
+ // CHECK: entry
+ // CHECK-NONSTRICT-NOT: @llvm.launder.invariant.group
+ // CHECK-STRICT: @llvm.launder.invariant.group
+ // CHECK: ret void
+ TestVirtualFn *d = __builtin_launder(Arr);
+}
+
+// CHECK-LABEL: define void @test_builtin_launder_array_nested(
+extern "C" void test_builtin_launder_array_nested(TestVirtualFn (&Arr)[5][2]) {
+ // CHECK: entry
+ // CHECK-NONSTRICT-NOT: @llvm.launder.invariant.group
+ // CHECK-STRICT: @llvm.launder.invariant.group
+ // CHECK: ret void
+ using RetTy = TestVirtualFn(*)[2];
+ RetTy d = __builtin_launder(Arr);
+}
+
+// CHECK-LABEL: define void @test_builtin_launder_array_no_invariant(
+extern "C" void test_builtin_launder_array_no_invariant(TestNoInvariant (&Arr)[5]) {
+ // CHECK: entry
+ // CHECK-NOT: @llvm.launder.invariant.group
+ // CHECK: ret void
+ TestNoInvariant *d = __builtin_launder(Arr);
+}
+
+// CHECK-LABEL: define void @test_builtin_launder_array_nested_no_invariant(
+extern "C" void test_builtin_launder_array_nested_no_invariant(TestNoInvariant (&Arr)[5][2]) {
+ // CHECK: entry
+ // CHECK-NOT: @llvm.launder.invariant.group
+ // CHECK: ret void
+ using RetTy = TestNoInvariant(*)[2];
+ RetTy d = __builtin_launder(Arr);
+}
+
+template <class Member>
+struct WithMember {
+ Member mem;
+};
+
+template struct WithMember<TestVirtualFn[5]>;
+
+// CHECK-LABEL: define void @test_builtin_launder_member_array(
+extern "C" void test_builtin_launder_member_array(WithMember<TestVirtualFn[5]> *p) {
+ // CHECK: entry
+ // CHECK-NONSTRICT-NOT: @llvm.launder.invariant.group
+ // CHECK-STRICT: @llvm.launder.invariant.group
+ // CHECK: ret void
+ auto *d = __builtin_launder(p);
+}
+
+template struct WithMember<TestVirtualFn[5][2]>;
+
+// CHECK-LABEL: define void @test_builtin_launder_member_array_nested(
+extern "C" void test_builtin_launder_member_array_nested(WithMember<TestVirtualFn[5][2]> *p) {
+ // CHECK: entry
+ // CHECK-NONSTRICT-NOT: @llvm.launder.invariant.group
+ // CHECK-STRICT: @llvm.launder.invariant.group
+ // CHECK: ret void
+ auto *d = __builtin_launder(p);
+}
+
+template struct WithMember<TestNoInvariant[5]>;
+
+// CHECK-LABEL: define void @test_builtin_launder_member_array_no_invariant(
+extern "C" void test_builtin_launder_member_array_no_invariant(WithMember<TestNoInvariant[5]> *p) {
+ // CHECK: entry
+ // CHECK-NOT: @llvm.launder.invariant.group
+ // CHECK: ret void
+ auto *d = __builtin_launder(p);
+}
+
+template struct WithMember<TestNoInvariant[5][2]>;
+
+// CHECK-LABEL: define void @test_builtin_launder_member_array_nested_no_invariant(
+extern "C" void test_builtin_launder_member_array_nested_no_invariant(WithMember<TestNoInvariant[5][2]> *p) {
+ // CHECK: entry
+ // CHECK-NOT: @llvm.launder.invariant.group
+ // CHECK: ret void
+ auto *d = __builtin_launder(p);
+}
+
+template <class T>
+struct WithBase : T {};
+
+template struct WithBase<TestNoInvariant>;
+
+// CHECK-LABEL: define void @test_builtin_launder_base_no_invariant(
+extern "C" void test_builtin_launder_base_no_invariant(WithBase<TestNoInvariant> *p) {
+ // CHECK: entry
+ // CHECK-NOT: @llvm.launder.invariant.group
+ // CHECK: ret void
+ auto *d = __builtin_launder(p);
+}
+
+template struct WithBase<TestVirtualFn>;
+
+// CHECK-LABEL: define void @test_builtin_launder_base(
+extern "C" void test_builtin_launder_base(WithBase<TestVirtualFn> *p) {
+ // CHECK: entry
+ // CHECK-NONSTRICT-NOT: @llvm.launder.invariant.group
+ // CHECK-STRICT: @llvm.launder.invariant.group
+ // CHECK: ret void
+ auto *d = __builtin_launder(p);
+}
+
+/// The test cases in this namespace technically need to be laundered according
+/// to the language in the standard (ie they have const or reference subobjects)
+/// but LLVM doesn't currently optimize on these cases -- so Clang emits
+/// __builtin_launder as a nop.
+///
+/// NOTE: Adding optimizations for these cases later is an LTO ABI break. That's
+/// probably OK for now -- but is something to keep in mind.
+namespace pessimizing_cases {
+
+struct TestConstMember {
+ const int x;
+};
+
+// CHECK-LABEL: define void @test_builtin_launder_const_member
+extern "C" void test_builtin_launder_const_member(TestConstMember *p) {
+ // CHECK: entry
+ // CHECK-NOT: @llvm.launder.invariant.group
+ // CHECK: ret void
+ TestConstMember *d = __builtin_launder(p);
+}
+
+struct TestConstSubobject {
+ TestConstMember x;
+};
+
+// CHECK-LABEL: define void @test_builtin_launder_const_subobject
+extern "C" void test_builtin_launder_const_subobject(TestConstSubobject *p) {
+ // CHECK: entry
+ // CHECK-NOT: @llvm.launder.invariant.group
+ // CHECK: ret void
+ TestConstSubobject *d = __builtin_launder(p);
+}
+
+struct TestConstObject {
+ const struct TestConstMember x;
+};
+
+// CHECK-LABEL: define void @test_builtin_launder_const_object
+extern "C" void test_builtin_launder_const_object(TestConstObject *p) {
+ // CHECK: entry
+ // CHECK-NOT: @llvm.launder.invariant.group
+ // CHECK: ret void
+ TestConstObject *d = __builtin_launder(p);
+}
+
+struct TestReferenceMember {
+ int &x;
+};
+
+// CHECK-LABEL: define void @test_builtin_launder_reference_member
+extern "C" void test_builtin_launder_reference_member(TestReferenceMember *p) {
+ // CHECK: entry
+ // CHECK-NOT: @llvm.launder.invariant.group
+ // CHECK: ret void
+ TestReferenceMember *d = __builtin_launder(p);
+}
+
+} // namespace pessimizing_cases
diff --git a/src/llvm-project/clang/test/CodeGenCXX/builtin-operator-new-delete.cpp b/src/llvm-project/clang/test/CodeGenCXX/builtin-operator-new-delete.cpp
new file mode 100644
index 0000000..712805a
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/builtin-operator-new-delete.cpp
@@ -0,0 +1,71 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown %s \
+// RUN: -faligned-allocation -fsized-deallocation -emit-llvm -o - \
+// RUN: | FileCheck %s
+
+typedef __SIZE_TYPE__ size_t;
+
+// Declare an 'operator new' template to tickle a bug in __builtin_operator_new.
+template<typename T> void *operator new(size_t, int (*)(T));
+
+// Ensure that this declaration doesn't cause operator new to lose its
+// 'noalias' attribute.
+void *operator new(size_t);
+
+namespace std {
+ struct nothrow_t {};
+ enum class align_val_t : size_t { __zero = 0,
+ __max = (size_t)-1 };
+}
+std::nothrow_t nothrow;
+
+// Declare the reserved placement operators.
+void *operator new(size_t, void*) throw();
+void operator delete(void*, void*) throw();
+void *operator new[](size_t, void*) throw();
+void operator delete[](void*, void*) throw();
+
+// Declare the replaceable global allocation operators.
+void *operator new(size_t, const std::nothrow_t &) throw();
+void *operator new[](size_t, const std::nothrow_t &) throw();
+void operator delete(void *, const std::nothrow_t &) throw();
+void operator delete[](void *, const std::nothrow_t &) throw();
+
+// Declare some other placement operators.
+void *operator new(size_t, void*, bool) throw();
+void *operator new[](size_t, void*, bool) throw();
+
+
+// CHECK-LABEL: define void @test_basic(
+extern "C" void test_basic() {
+ // CHECK: call i8* @_Znwm(i64 4) [[ATTR_BUILTIN_NEW:#[^ ]*]]
+ // CHECK: call void @_ZdlPv({{.*}}) [[ATTR_BUILTIN_DELETE:#[^ ]*]]
+ // CHECK: ret void
+ __builtin_operator_delete(__builtin_operator_new(4));
+}
+// CHECK: declare noalias i8* @_Znwm(i64) [[ATTR_NOBUILTIN:#[^ ]*]]
+// CHECK: declare void @_ZdlPv(i8*) [[ATTR_NOBUILTIN_NOUNWIND:#[^ ]*]]
+
+// CHECK-LABEL: define void @test_aligned_alloc(
+extern "C" void test_aligned_alloc() {
+ // CHECK: call i8* @_ZnwmSt11align_val_t(i64 4, i64 4) [[ATTR_BUILTIN_NEW:#[^ ]*]]
+ // CHECK: call void @_ZdlPvSt11align_val_t({{.*}}, i64 4) [[ATTR_BUILTIN_DELETE:#[^ ]*]]
+ __builtin_operator_delete(__builtin_operator_new(4, std::align_val_t(4)), std::align_val_t(4));
+}
+// CHECK: declare noalias i8* @_ZnwmSt11align_val_t(i64, i64) [[ATTR_NOBUILTIN:#[^ ]*]]
+// CHECK: declare void @_ZdlPvSt11align_val_t(i8*, i64) [[ATTR_NOBUILTIN_NOUNWIND:#[^ ]*]]
+
+
+// CHECK-LABEL: define void @test_sized_delete(
+extern "C" void test_sized_delete() {
+ // CHECK: call i8* @_Znwm(i64 4) [[ATTR_BUILTIN_NEW:#[^ ]*]]
+ // CHECK: call void @_ZdlPvm({{.*}}, i64 4) [[ATTR_BUILTIN_DELETE:#[^ ]*]]
+ __builtin_operator_delete(__builtin_operator_new(4), 4);
+}
+// CHECK: declare void @_ZdlPvm(i8*, i64) [[ATTR_NOBUILTIN_UNWIND:#[^ ]*]]
+
+
+// CHECK-DAG: attributes [[ATTR_NOBUILTIN]] = {{[{].*}} nobuiltin {{.*[}]}}
+// CHECK-DAG: attributes [[ATTR_NOBUILTIN_NOUNWIND]] = {{[{].*}} nobuiltin nounwind {{.*[}]}}
+
+// CHECK-DAG: attributes [[ATTR_BUILTIN_NEW]] = {{[{].*}} builtin {{.*[}]}}
+// CHECK-DAG: attributes [[ATTR_BUILTIN_DELETE]] = {{[{].*}} builtin {{.*[}]}}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/builtins-arm-exclusive.cpp b/src/llvm-project/clang/test/CodeGenCXX/builtins-arm-exclusive.cpp
new file mode 100644
index 0000000..06f7a02
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/builtins-arm-exclusive.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -Wall -Werror -triple thumbv8-linux-gnueabi -fno-signed-char -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -Wall -Werror -triple arm64-apple-ios7.0 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-ARM64
+
+bool b;
+
+// CHECK-LABEL: @_Z10test_ldrexv()
+// CHECK: call i32 @llvm.arm.ldrex.p0i8(i8* @b)
+
+// CHECK-ARM64-LABEL: @_Z10test_ldrexv()
+// CHECK-ARM64: call i64 @llvm.aarch64.ldxr.p0i8(i8* @b)
+
+void test_ldrex() {
+ b = __builtin_arm_ldrex(&b);
+}
+
+// CHECK-LABEL: @_Z10tset_strexv()
+// CHECK: %{{.*}} = call i32 @llvm.arm.strex.p0i8(i32 1, i8* @b)
+
+// CHECK-ARM64-LABEL: @_Z10tset_strexv()
+// CHECK-ARM64: %{{.*}} = call i32 @llvm.aarch64.stxr.p0i8(i64 1, i8* @b)
+
+void tset_strex() {
+ __builtin_arm_strex(true, &b);
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/builtins-systemz-zvector.cpp b/src/llvm-project/clang/test/CodeGenCXX/builtins-systemz-zvector.cpp
new file mode 100644
index 0000000..aedb30f
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/builtins-systemz-zvector.cpp
@@ -0,0 +1,50 @@
+// REQUIRES: systemz-registered-target
+// RUN: %clang_cc1 -target-cpu z13 -triple s390x-linux-gnu \
+// RUN: -fzvector -fno-lax-vector-conversions -std=c++11 \
+// RUN: -Wall -Wno-unused -Werror -emit-llvm %s -o - | FileCheck %s
+
+bool gb;
+
+// There was an issue where we weren't properly converting constexprs to
+// vectors with elements of the appropriate width. (e.g.
+// (vector signed short)0 would be lowered as [4 x i32] in some cases)
+
+// CHECK-LABEL: @_Z8testIntsDv4_i
+void testInts(vector int VI) {
+ constexpr vector int CI1 = (vector int)0LL;
+ // CHECK: icmp
+ gb = (VI == CI1)[0];
+
+ // Likewise for float inits.
+ constexpr vector int CI2 = (vector int)char(0);
+ // CHECK: icmp
+ gb = (VI == CI2)[0];
+
+ constexpr vector int CF1 = (vector int)0.0;
+ // CHECK: icmp
+ gb = (VI == CF1)[0];
+
+ constexpr vector int CF2 = (vector int)0.0f;
+ // CHECK: icmp
+ gb = (VI == CF2)[0];
+}
+
+// CHECK-LABEL: @_Z10testFloatsDv2_d
+void testFloats(vector double VD) {
+ constexpr vector double CI1 = (vector double)0LL;
+ // CHECK: fcmp
+ gb = (VD == CI1)[0];
+
+ // Likewise for float inits.
+ constexpr vector double CI2 = (vector double)char(0);
+ // CHECK: fcmp
+ gb = (VD == CI2)[0];
+
+ constexpr vector double CF1 = (vector double)0.0;
+ // CHECK: fcmp
+ gb = (VD == CF1)[0];
+
+ constexpr vector double CF2 = (vector double)0.0f;
+ // CHECK: fcmp
+ gb = (VD == CF2)[0];
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/builtins.cpp b/src/llvm-project/clang/test/CodeGenCXX/builtins.cpp
new file mode 100644
index 0000000..33c714e
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/builtins.cpp
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -triple=x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s
+
+// PR8839
+extern "C" char memmove();
+
+int main() {
+ // CHECK: call {{signext i8|i8}} @memmove()
+ return memmove();
+}
+
+struct S;
+// CHECK: define {{.*}} @_Z9addressofbR1SS0_(
+S *addressof(bool b, S &s, S &t) {
+ // CHECK: %[[LVALUE:.*]] = phi
+ // CHECK: ret {{.*}}* %[[LVALUE]]
+ return __builtin_addressof(b ? s : t);
+}
+
+extern "C" int __builtin_abs(int); // #1
+long __builtin_abs(long); // #2
+extern "C" int __builtin_abs(int); // #3
+
+int x = __builtin_abs(-2);
+// CHECK: store i32 2, i32* @x, align 4
+
+long y = __builtin_abs(-2l);
+// CHECK: [[Y:%.+]] = call i64 @_Z13__builtin_absl(i64 -2)
+// CHECK: store i64 [[Y]], i64* @y, align 8
+
+extern const char char_memchr_arg[32];
+char *memchr_result = __builtin_char_memchr(char_memchr_arg, 123, 32);
+// CHECK: call i8* @memchr(i8* getelementptr inbounds ([32 x i8], [32 x i8]* @char_memchr_arg, i32 0, i32 0), i32 123, i64 32)
+
+int constexpr_overflow_result() {
+ constexpr int x = 1;
+ // CHECK: alloca i32
+ constexpr int y = 2;
+ // CHECK: alloca i32
+ int z;
+ // CHECK: [[Z:%.+]] = alloca i32
+
+ __builtin_sadd_overflow(x, y, &z);
+ return z;
+ // CHECK: [[RET_PTR:%.+]] = extractvalue { i32, i1 } %0, 0
+ // CHECK: store i32 [[RET_PTR]], i32* [[Z]]
+ // CHECK: [[RET_VAL:%.+]] = load i32, i32* [[Z]]
+ // CHECK: ret i32 [[RET_VAL]]
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/c-linkage.cpp b/src/llvm-project/clang/test/CodeGenCXX/c-linkage.cpp
new file mode 100644
index 0000000..0f4c327
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/c-linkage.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -o - %s | FileCheck %s
+// pr6644
+
+extern "C" {
+ namespace N {
+ struct X {
+ virtual void f();
+ };
+ void X::f() { }
+ }
+}
+
+// CHECK-LABEL: define {{.*}}void @_ZN1N1X1fEv
+
+extern "C" {
+ static void test2_f() {
+ }
+ // CHECK-LABEL: define internal {{.*}}void @_ZL7test2_fv
+ static void test2_f(int x) {
+ }
+ // CHECK-LABEL: define internal {{.*}}void @_ZL7test2_fi
+ void test2_use() {
+ test2_f();
+ test2_f(42);
+ }
+}
+
+extern "C" {
+ struct test3_s {
+ };
+ bool operator==(const int& a, const test3_s& b) {
+ }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/c99-variable-length-array.cpp b/src/llvm-project/clang/test/CodeGenCXX/c99-variable-length-array.cpp
new file mode 100644
index 0000000..2cd8e11
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/c99-variable-length-array.cpp
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
+struct X {
+ X();
+ ~X();
+};
+
+struct Y {
+ Y();
+ ~Y();
+};
+
+// CHECK-LABEL: define void @_Z1fiPPKc(
+void f(int argc, const char* argv[]) {
+ // CHECK: call void @_ZN1XC1Ev
+ X x;
+ // CHECK: call i8* @llvm.stacksave(
+ const char *argv2[argc];
+ // CHECK: call void @_ZN1YC1Ev
+ Y y;
+ for (int i = 0; i != argc; ++i)
+ argv2[i] = argv[i];
+
+ // CHECK: call void @_ZN1YD1Ev
+ // CHECK: call void @llvm.stackrestore
+ // CHECK: call void @_ZN1XD1Ev
+ // CHECK: ret void
+}
+
+namespace PR11744 {
+ // Make sure this doesn't crash; there was a use-after-free issue
+ // for this testcase.
+ template<typename T> int f(int n) {
+ T arr[3][n];
+ return 3;
+ }
+ int test = f<int>(0);
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/call-arg-zero-temp.cpp b/src/llvm-project/clang/test/CodeGenCXX/call-arg-zero-temp.cpp
new file mode 100644
index 0000000..beef2fd
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/call-arg-zero-temp.cpp
@@ -0,0 +1,23 @@
+// REQUIRES: x86-registered-target
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -S %s -o %t-64.s
+// RUN: FileCheck -check-prefix CHECK-LP64 --input-file=%t-64.s %s
+// RUN: %clang_cc1 -triple i386-apple-darwin -S %s -o %t-32.s
+// RUN: FileCheck -check-prefix CHECK-LP32 --input-file=%t-32.s %s
+
+
+extern "C" int printf(...);
+
+struct obj{ int a; float b; double d; };
+
+void foo(obj o) {
+ printf("%d %f %f\n", o.a, o.b, o.d);
+}
+
+int main() {
+ obj o = obj();
+ foo(obj());
+}
+
+// CHECK-LP64: callq __Z3foo3obj
+
+// CHECK-LP32: calll __Z3foo3obj
diff --git a/src/llvm-project/clang/test/CodeGenCXX/call-with-static-chain.cpp b/src/llvm-project/clang/test/CodeGenCXX/call-with-static-chain.cpp
new file mode 100644
index 0000000..ac1149b
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/call-with-static-chain.cpp
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -o - %s | FileCheck -check-prefix=CHECK32 %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck -check-prefix=CHECK64 %s
+
+struct A {
+ long x, y;
+};
+
+struct B {
+ long x, y, z, w;
+};
+
+extern "C" {
+
+int f1(A, A, A, A);
+B f2(void);
+_Complex float f3(void);
+A &f4();
+
+}
+
+void test() {
+ A a;
+
+ // CHECK32: call i32 bitcast (i32 (i32, i32, i32, i32, i32, i32, i32, i32)* @f1 to i32 (i8*, i32, i32, i32, i32, i32, i32, i32, i32)*)(i8* nest bitcast (i32 (i32, i32, i32, i32, i32, i32, i32, i32)* @f1 to i8*)
+ // CHECK64: call i32 bitcast (i32 (i64, i64, i64, i64, i64, i64, %struct.A*)* @f1 to i32 (i8*, i64, i64, i64, i64, i64, i64, %struct.A*)*)(i8* nest bitcast (i32 (i64, i64, i64, i64, i64, i64, %struct.A*)* @f1 to i8*)
+ __builtin_call_with_static_chain(f1(a, a, a, a), f1);
+
+ // CHECK32: call void bitcast (void (%struct.B*)* @f2 to void (%struct.B*, i8*)*)(%struct.B* sret %{{[0-9a-z]+}}, i8* nest bitcast (void (%struct.B*)* @f2 to i8*))
+ // CHECK64: call void bitcast (void (%struct.B*)* @f2 to void (%struct.B*, i8*)*)(%struct.B* sret %{{[0-9a-z]+}}, i8* nest bitcast (void (%struct.B*)* @f2 to i8*))
+ __builtin_call_with_static_chain(f2(), f2);
+
+ // CHECK32: call i64 bitcast (i64 ()* @f3 to i64 (i8*)*)(i8* nest bitcast (i64 ()* @f3 to i8*))
+ // CHECK64: call <2 x float> bitcast (<2 x float> ()* @f3 to <2 x float> (i8*)*)(i8* nest bitcast (<2 x float> ()* @f3 to i8*))
+ __builtin_call_with_static_chain(f3(), f3);
+
+ // CHECK32: call dereferenceable(8) %struct.A* bitcast (%struct.A* ()* @f4 to %struct.A* (i8*)*)(i8* nest bitcast (%struct.A* ()* @f4 to i8*))
+ // CHECK64: call dereferenceable(16) %struct.A* bitcast (%struct.A* ()* @f4 to %struct.A* (i8*)*)(i8* nest bitcast (%struct.A* ()* @f4 to i8*))
+ __builtin_call_with_static_chain(f4(), f4);
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/captured-statements.cpp b/src/llvm-project/clang/test/CodeGenCXX/captured-statements.cpp
new file mode 100644
index 0000000..c8832f1
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/captured-statements.cpp
@@ -0,0 +1,211 @@
+// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -emit-llvm %s -o %t -debug-info-kind=limited
+// RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-1
+// RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-2
+// RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-3
+// RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-4
+// RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-5
+// RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-6
+// RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-7
+
+struct Foo {
+ int x;
+ float y;
+ ~Foo() {}
+};
+
+struct TestClass {
+ int x;
+
+ TestClass() : x(0) {};
+ void MemberFunc() {
+ Foo f;
+ #pragma clang __debug captured
+ {
+ static double inner = x;
+ (void)inner;
+ f.y = x;
+ }
+ }
+};
+
+void test1() {
+ TestClass c;
+ c.MemberFunc();
+ // CHECK-1: %[[Capture:struct\.anon[\.0-9]*]] = type { %struct.TestClass*, %struct.Foo* }
+ // CHECK-1: [[INNER:@.+]] = {{.+}} global double
+
+ // CHECK-1: define {{.*}} void @_ZN9TestClass10MemberFuncEv
+ // CHECK-1: alloca %struct.anon
+ // CHECK-1: getelementptr inbounds %[[Capture]], %[[Capture]]* %{{[^,]*}}, i32 0, i32 0
+ // CHECK-1: getelementptr inbounds %[[Capture]], %[[Capture]]* %{{[^,]*}}, i32 0, i32 1
+ // CHECK-1: store %struct.Foo* %f, %struct.Foo**
+ // CHECK-1: call void @[[HelperName:[\.A-Za-z0-9_]+]](%[[Capture]]*
+ // CHECK-1: call {{.*}}FooD1Ev
+ // CHECK-1: ret
+}
+
+// CHECK-1: define internal {{.*}}void @[[HelperName]]
+// CHECK-1: getelementptr inbounds %[[Capture]], %[[Capture]]* {{[^,]*}}, i32 0, i32 0
+// CHECK-1: call {{.*}}i32 @__cxa_guard_acquire(
+// CHECK-1: store double %{{.+}}, double* [[INNER]],
+// CHECK-1: call {{.*}}void @__cxa_guard_release(
+// CHECK-1: getelementptr inbounds %struct.TestClass, %struct.TestClass* {{[^,]*}}, i32 0, i32 0
+// CHECK-1: getelementptr inbounds %[[Capture]], %[[Capture]]* {{[^,]*}}, i32 0, i32 1
+
+void test2(int x) {
+ int y = [&]() {
+ #pragma clang __debug captured
+ {
+ x++;
+ }
+ return x;
+ }();
+
+ // CHECK-2-LABEL: define {{.*}}void @_Z5test2i
+ // CHECK-2: call {{.*}} @[[Lambda:["$\w]+]]
+ //
+ // CHECK-2: define internal {{.*}} @[[Lambda]]
+ // CHECK-2: call void @[[HelperName:["$_A-Za-z0-9]+]](%[[Capture:.*]]*
+ //
+ // CHECK-2: define internal {{.*}}void @[[HelperName]]
+ // CHECK-2: getelementptr inbounds %[[Capture]], %[[Capture]]*
+ // CHECK-2: load i32*, i32**
+ // CHECK-2: load i32, i32*
+}
+
+void test3(int x) {
+ #pragma clang __debug captured
+ {
+ x = [=]() { return x + 1; } ();
+ }
+ x = [=]() { return x + 1; }();
+
+ // CHECK-3: %[[Capture:struct\.anon[\.0-9]*]] = type { i32* }
+
+ // CHECK-3-LABEL: define {{.*}}void @_Z5test3i
+ // CHECK-3: store i32*
+ // CHECK-3: call void @{{.*}}__captured_stmt
+ // CHECK-3: ret void
+}
+
+void test4() {
+ #pragma clang __debug captured
+ {
+ Foo f;
+ f.x = 5;
+ }
+ // CHECK-4-LABEL: define {{.*}}void @_Z5test4v
+ // CHECK-4: call void @[[HelperName:[\."$_A-Za-z0-9]+]](%[[Capture:.*]]*
+ // CHECK-4: ret void
+ //
+ // CHECK-4: define internal {{.*}}void @[[HelperName]]
+ // CHECK-4: store i32 5, i32*
+ // CHECK-4: call {{.*}}FooD1Ev
+}
+
+template <typename T, int id>
+void touch(const T &) {}
+
+template <typename T, unsigned id>
+void template_capture_var() {
+ T x;
+ #pragma clang __debug captured
+ {
+ touch<T, id>(x);
+ }
+}
+
+template <typename T, int id>
+class Val {
+ T v;
+public:
+ void set() {
+ #pragma clang __debug captured
+ {
+ touch<T, id>(v);
+ }
+ }
+
+ template <typename U, int id2>
+ void foo(U u) {
+ #pragma clang __debug captured
+ {
+ touch<U, id + id2>(u);
+ }
+ }
+};
+
+void test_capture_var() {
+ // CHECK-5: define {{.*}} void @_Z20template_capture_varIiLj201EEvv
+ // CHECK-5-NOT: }
+ // CHECK-5: store i32*
+ // CHECK-5: call void @__captured_stmt
+ // CHECK-5-NEXT: ret void
+ template_capture_var<int, 201>();
+
+ // CHECK-5: define {{.*}} void @_ZN3ValIfLi202EE3setEv
+ // CHECK-5-NOT: }
+ // CHECK-5: store %class.Val*
+ // CHECK-5: call void @__captured_stmt
+ // CHECK-5-NEXT: ret void
+ Val<float, 202> Obj;
+ Obj.set();
+
+ // CHECK-5: define {{.*}} void @_ZN3ValIfLi202EE3fooIdLi203EEEvT_
+ // CHECK-5-NOT: }
+ // CHECK-5: store %class.Val*
+ // CHECK-5: store double
+ // CHECK-5: call void @__captured_stmt
+ // CHECK-5-NEXT: ret void
+ Obj.foo<double, 203>(1.0);
+}
+
+template <typename T>
+void template_capture_lambda() {
+ T x, y;
+ [=, &y]() {
+ #pragma clang __debug captured
+ {
+ y += x;
+ }
+ }();
+}
+
+void test_capture_lambda() {
+ // CHECK-6: define {{.*}} void @_ZZ23template_capture_lambdaIiEvvENKUlvE_clEv
+ // CHECK-6-NOT: }
+ // CHECK-6: store i32*
+ // CHECK-6: store i32*
+ // CHECK-6: call void @__captured_stmt
+ // CHECK-6-NEXT: ret void
+ template_capture_lambda<int>();
+}
+
+inline int test_captured_linkage() {
+ // CHECK-7: @_ZZ21test_captured_linkagevE1i = linkonce_odr {{(dso_local )?}}global i32 0
+ int j;
+ #pragma clang __debug captured
+ {
+ static int i = 0;
+ j = ++i;
+ }
+ return j;
+}
+void call_test_captured_linkage() {
+ test_captured_linkage();
+}
+
+// CHECK-1-DAG: !DILocalVariable(name: "this", {{.*}}, flags: DIFlagArtificial | DIFlagObjectPointer)
+// CHECK-1-DAG: !DILocalVariable(name: "__context", {{.*}}, flags: DIFlagArtificial)
+// CHECK-2-DAG: !DILocalVariable(name: "this", {{.*}}, flags: DIFlagArtificial | DIFlagObjectPointer)
+// CHECK-2-DAG: !DILocalVariable(name: "__context", {{.*}}, flags: DIFlagArtificial)
+// CHECK-3-DAG: !DILocalVariable(name: "this", {{.*}}, flags: DIFlagArtificial | DIFlagObjectPointer)
+// CHECK-3-DAG: !DILocalVariable(name: "__context", {{.*}}, flags: DIFlagArtificial)
+// CHECK-4-DAG: !DILocalVariable(name: "this", {{.*}}, flags: DIFlagArtificial | DIFlagObjectPointer)
+// CHECK-4-DAG: !DILocalVariable(name: "__context", {{.*}}, flags: DIFlagArtificial)
+// CHECK-5-DAG: !DILocalVariable(name: "this", {{.*}}, flags: DIFlagArtificial | DIFlagObjectPointer)
+// CHECK-5-DAG: !DILocalVariable(name: "__context", {{.*}}, flags: DIFlagArtificial)
+// CHECK-6-DAG: !DILocalVariable(name: "this", {{.*}}, flags: DIFlagArtificial | DIFlagObjectPointer)
+// CHECK-6-DAG: !DILocalVariable(name: "__context", {{.*}}, flags: DIFlagArtificial)
+// CHECK-7-DAG: !DILocalVariable(name: "this", {{.*}}, flags: DIFlagArtificial | DIFlagObjectPointer)
+// CHECK-7-DAG: !DILocalVariable(name: "__context", {{.*}}, flags: DIFlagArtificial)
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cast-conversion.cpp b/src/llvm-project/clang/test/CodeGenCXX/cast-conversion.cpp
new file mode 100644
index 0000000..ce8f820
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cast-conversion.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm %s -o - | \
+// RUN: FileCheck %s
+// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -emit-llvm %s -o - | \
+// RUN: FileCheck %s
+
+struct A {
+ A(int);
+};
+
+struct B {
+ B(A);
+};
+
+int main () {
+ (B)10;
+ B(10);
+ static_cast<B>(10);
+}
+
+// CHECK: call void @_ZN1AC1Ei
+// CHECK: call void @_ZN1BC1E1A
+// CHECK: call void @_ZN1AC1Ei
+// CHECK: call void @_ZN1BC1E1A
+// CHECK: call void @_ZN1AC1Ei
+// CHECK: call void @_ZN1BC1E1A
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cast-to-ref-bool.cpp b/src/llvm-project/clang/test/CodeGenCXX/cast-to-ref-bool.cpp
new file mode 100644
index 0000000..1064720
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cast-to-ref-bool.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - %s | FileCheck %s
+
+// CHECK-LABEL: main
+int main(int argc, char **argv) {
+ // CHECK: load i8, i8* %
+ // CHECK-NEXT: trunc i8 %{{.+}} to i1
+ bool b = (bool &)argv[argc][1];
+ return b;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/castexpr-basepathsize-threshold.cpp b/src/llvm-project/clang/test/CodeGenCXX/castexpr-basepathsize-threshold.cpp
new file mode 100644
index 0000000..61272b1
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/castexpr-basepathsize-threshold.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 %s -emit-llvm-only -o -
+
+// https://bugs.llvm.org/show_bug.cgi?id=38356
+// We only check that we do not crash.
+
+// ASAN increases stack usage, so we are hitting stack overflow before reaching
+// recursive template instantiation limit.
+// XFAIL: darwin && asan
+
+template <typename a, a b(unsigned), int c, unsigned...>
+struct d : d<a, b, c - 1> {};
+template <typename a, a b(unsigned), unsigned... e>
+struct d<a, b, 0, e...> {
+ a f[0];
+};
+struct g {
+ static g h(unsigned);
+};
+struct i {
+ void j() const;
+ // Current maximum depth of recursive template instantiation is 1024,
+ // thus, this \/ threshold value is used here. BasePathSize in CastExpr might
+ // not fit it, so we are testing that we do fit it.
+ // If -ftemplate-depth= is provided, larger values (4096 and up) cause crashes
+ // elsewhere.
+ d<g, g::h, (1U << 10U) - 2U> f;
+};
+void i::j() const {
+ const void *k{f.f};
+ (void)k;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/casts.cpp b/src/llvm-project/clang/test/CodeGenCXX/casts.cpp
new file mode 100644
index 0000000..436b722
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/casts.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 %s -emit-llvm -o %t
+
+// PR5248
+namespace PR5248 {
+struct A {
+ void copyFrom(const A &src);
+ void addRef(void);
+
+ A& operator=(int);
+};
+
+void A::copyFrom(const A &src) {
+ ((A &)src).addRef();
+}
+}
+
+// reinterpret_cast to self
+void test(PR5248::A* a) {
+ reinterpret_cast<PR5248::A&>(*a) = 17;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/catch-implicit-integer-sign-changes-true-negatives.cpp b/src/llvm-project/clang/test/CodeGenCXX/catch-implicit-integer-sign-changes-true-negatives.cpp
new file mode 100644
index 0000000..9534938
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/catch-implicit-integer-sign-changes-true-negatives.cpp
@@ -0,0 +1,149 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK
+// RUN: %clang_cc1 -fsanitize=implicit-integer-sign-change -fno-sanitize-recover=implicit-integer-sign-change -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-NORECOVER
+// RUN: %clang_cc1 -fsanitize=implicit-integer-sign-change -fsanitize-recover=implicit-integer-sign-change -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-RECOVER
+// RUN: %clang_cc1 -fsanitize=implicit-integer-sign-change -fsanitize-trap=implicit-integer-sign-change -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-TRAP
+
+extern "C" { // Disable name mangling.
+
+// ========================================================================== //
+// The expected true-negatives.
+// ========================================================================== //
+
+// Sanitization is explicitly disabled.
+// ========================================================================== //
+
+// CHECK-LABEL: @blacklist_0
+__attribute__((no_sanitize("undefined"))) unsigned int blacklist_0(signed int src) {
+ // We are not in "undefined" group, so that doesn't work.
+ // CHECK-SANITIZE: call
+ // CHECK: }
+ return src;
+}
+
+// CHECK-LABEL: @blacklist_1
+__attribute__((no_sanitize("integer"))) unsigned int blacklist_1(signed int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return src;
+}
+
+// CHECK-LABEL: @blacklist_2
+__attribute__((no_sanitize("implicit-conversion"))) unsigned int blacklist_2(signed int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return src;
+}
+
+// CHECK-LABEL: @blacklist_3
+__attribute__((no_sanitize("implicit-integer-sign-change"))) unsigned int blacklist_3(signed int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return src;
+}
+
+// Explicit sign-changing conversions.
+// ========================================================================== //
+
+// CHECK-LABEL: @explicit_signed_int_to_unsigned_int
+unsigned int explicit_signed_int_to_unsigned_int(signed int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return (unsigned int)src;
+}
+
+// CHECK-LABEL: @explicit_unsigned_int_to_signed_int
+signed int explicit_unsigned_int_to_signed_int(unsigned int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return (signed int)src;
+}
+
+// Explicit NOP conversions.
+// ========================================================================== //
+
+// CHECK-LABEL: @explicit_unsigned_int_to_unsigned_int
+unsigned int explicit_unsigned_int_to_unsigned_int(unsigned int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return (unsigned int)src;
+}
+
+// CHECK-LABEL: @explicit_signed_int_to_signed_int
+signed int explicit_signed_int_to_signed_int(signed int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return (signed int)src;
+}
+
+// Explicit functional sign-changing casts.
+// ========================================================================== //
+
+using UnsignedInt = unsigned int;
+using SignedInt = signed int;
+
+// CHECK-LABEL: explicit_functional_unsigned_int_to_signed_int
+signed int explicit_functional_unsigned_int_to_signed_int(unsigned int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return SignedInt(src);
+}
+
+// CHECK-LABEL: @explicit_functional_signed_int_to_unsigned_int
+unsigned int explicit_functional_signed_int_to_unsigned_int(signed int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return UnsignedInt(src);
+}
+
+// Explicit functional NOP casts.
+// ========================================================================== //
+
+// CHECK-LABEL: @explicit_functional_unsigned_int_to_unsigned_int
+unsigned int explicit_functional_unsigned_int_to_unsigned_int(unsigned int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return UnsignedInt(src);
+}
+
+// CHECK-LABEL: @explicit_functional_signed_int_to_signed_int
+signed int explicit_functional_signed_int_to_signed_int(signed int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return SignedInt(src);
+}
+
+// Explicit C++-style sign-changing casts.
+// ========================================================================== //
+
+// CHECK-LABEL: @explicit_cppstyle_unsigned_int_to_signed_int
+signed int explicit_cppstyle_unsigned_int_to_signed_int(unsigned int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return static_cast<signed int>(src);
+}
+
+// CHECK-LABEL: @explicit_cppstyle_signed_int_to_unsigned_int
+unsigned int explicit_cppstyle_signed_int_to_unsigned_int(signed int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return static_cast<unsigned int>(src);
+}
+
+// Explicit C++-style casts NOP casts.
+// ========================================================================== //
+
+// CHECK-LABEL: @explicit_cppstyle_unsigned_int_to_unsigned_int
+unsigned int explicit_cppstyle_unsigned_int_to_unsigned_int(unsigned int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return static_cast<unsigned int>(src);
+}
+
+// CHECK-LABEL: @explicit_cppstyle_signed_int_to_signed_int
+signed int explicit_cppstyle_signed_int_to_signed_int(signed int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return static_cast<signed int>(src);
+}
+
+} // extern "C"
diff --git a/src/llvm-project/clang/test/CodeGenCXX/catch-implicit-integer-truncations.cpp b/src/llvm-project/clang/test/CodeGenCXX/catch-implicit-integer-truncations.cpp
new file mode 100644
index 0000000..2902fe1
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/catch-implicit-integer-truncations.cpp
@@ -0,0 +1,256 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK
+// RUN: %clang_cc1 -fsanitize=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation -fno-sanitize-recover=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-NORECOVER
+// RUN: %clang_cc1 -fsanitize=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation -fsanitize-recover=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-RECOVER
+// RUN: %clang_cc1 -fsanitize=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation -fsanitize-trap=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-TRAP
+
+extern "C" { // Disable name mangling.
+
+// ========================================================================== //
+// Check that explicit cast does not interfere with implicit conversion
+// ========================================================================== //
+// These contain one implicit truncating conversion, and one explicit truncating cast.
+// We want to make sure that we still diagnose the implicit conversion.
+
+// Implicit truncation after explicit truncation.
+// CHECK-LABEL: @explicit_cast_interference0
+unsigned char explicit_cast_interference0(unsigned int c) {
+ // CHECK-SANITIZE: %[[ANYEXT:.*]] = zext i8 %[[DST:.*]] to i16, !nosanitize
+ // CHECK-SANITIZE: call
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return (unsigned short)c;
+}
+
+// Implicit truncation before explicit truncation.
+// CHECK-LABEL: @explicit_cast_interference1
+unsigned char explicit_cast_interference1(unsigned int c) {
+ // CHECK-SANITIZE: %[[ANYEXT:.*]] = zext i16 %[[DST:.*]] to i32, !nosanitize
+ // CHECK-SANITIZE: call
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ unsigned short b;
+ return (unsigned char)(b = c);
+}
+
+// ========================================================================== //
+// The expected true-negatives.
+// ========================================================================== //
+
+// Explicit truncating casts.
+// ========================================================================== //
+
+// CHECK-LABEL: @explicit_unsigned_int_to_unsigned_char
+unsigned char explicit_unsigned_int_to_unsigned_char(unsigned int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return (unsigned char)src;
+}
+
+// CHECK-LABEL: @explicit_signed_int_to_unsigned_char
+unsigned char explicit_signed_int_to_unsigned_char(signed int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return (unsigned char)src;
+}
+
+// CHECK-LABEL: @explicit_unsigned_int_to_signed_char
+signed char explicit_unsigned_int_to_signed_char(unsigned int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return (signed char)src;
+}
+
+// CHECK-LABEL: @explicit_signed_int_to_signed_char
+signed char explicit_signed_int_to_signed_char(signed int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return (signed char)src;
+}
+
+// Explicit NOP casts.
+// ========================================================================== //
+
+// CHECK-LABEL: @explicit_unsigned_int_to_unsigned_int
+unsigned int explicit_unsigned_int_to_unsigned_int(unsigned int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return (unsigned int)src;
+}
+
+// CHECK-LABEL: @explicit_signed_int_to_signed_int
+signed int explicit_signed_int_to_signed_int(signed int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return (signed int)src;
+}
+
+// CHECK-LABEL: @explicit_unsigned_char_to_signed_char
+unsigned char explicit_unsigned_char_to_signed_char(unsigned char src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return (unsigned char)src;
+}
+
+// CHECK-LABEL: @explicit_signed_char_to_signed_char
+signed char explicit_signed_char_to_signed_char(signed char src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return (signed char)src;
+}
+
+// Explicit functional truncating casts.
+// ========================================================================== //
+
+using UnsignedChar = unsigned char;
+using SignedChar = signed char;
+using UnsignedInt = unsigned int;
+using SignedInt = signed int;
+
+// CHECK-LABEL: @explicit_functional_unsigned_int_to_unsigned_char
+unsigned char explicit_functional_unsigned_int_to_unsigned_char(unsigned int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return UnsignedChar(src);
+}
+
+// CHECK-LABEL: @explicit_functional_signed_int_to_unsigned_char
+unsigned char explicit_functional_signed_int_to_unsigned_char(signed int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return UnsignedChar(src);
+}
+
+// CHECK-LABEL: @explicit_functional_unsigned_int_to_signed_char
+signed char explicit_functional_unsigned_int_to_signed_char(unsigned int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return SignedChar(src);
+}
+
+// CHECK-LABEL: @explicit_functional_signed_int_to_signed_char
+signed char explicit_functional_signed_int_to_signed_char(signed int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return SignedChar(src);
+}
+
+// Explicit functional NOP casts.
+// ========================================================================== //
+
+// CHECK-LABEL: @explicit_functional_unsigned_int_to_unsigned_int
+unsigned int explicit_functional_unsigned_int_to_unsigned_int(unsigned int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return UnsignedInt(src);
+}
+
+// CHECK-LABEL: @explicit_functional_signed_int_to_signed_int
+signed int explicit_functional_signed_int_to_signed_int(signed int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return SignedInt(src);
+}
+
+// CHECK-LABEL: @explicit_functional_unsigned_char_to_signed_char
+unsigned char explicit_functional_unsigned_char_to_signed_char(unsigned char src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return UnsignedChar(src);
+}
+
+// CHECK-LABEL: @explicit_functional_signed_char_to_signed_char
+signed char explicit_functional_signed_char_to_signed_char(signed char src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return SignedChar(src);
+}
+
+// Explicit C++-style casts truncating casts.
+// ========================================================================== //
+
+// CHECK-LABEL: @explicit_cppstyleunsigned_int_to_unsigned_char
+unsigned char explicit_cppstyleunsigned_int_to_unsigned_char(unsigned int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return static_cast<unsigned char>(src);
+}
+
+// CHECK-LABEL: @explicit_cppstylesigned_int_to_unsigned_char
+unsigned char explicit_cppstylesigned_int_to_unsigned_char(signed int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return static_cast<unsigned char>(src);
+}
+
+// CHECK-LABEL: @explicit_cppstyleunsigned_int_to_signed_char
+signed char explicit_cppstyleunsigned_int_to_signed_char(unsigned int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return static_cast<signed char>(src);
+}
+
+// CHECK-LABEL: @explicit_cppstylesigned_int_to_signed_char
+signed char explicit_cppstylesigned_int_to_signed_char(signed int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return static_cast<signed char>(src);
+}
+
+// Explicit C++-style casts NOP casts.
+// ========================================================================== //
+
+// CHECK-LABEL: @explicit_cppstyleunsigned_int_to_unsigned_int
+unsigned int explicit_cppstyleunsigned_int_to_unsigned_int(unsigned int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return static_cast<unsigned int>(src);
+}
+
+// CHECK-LABEL: @explicit_cppstylesigned_int_to_signed_int
+signed int explicit_cppstylesigned_int_to_signed_int(signed int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return static_cast<signed int>(src);
+}
+
+// CHECK-LABEL: @explicit_cppstyleunsigned_char_to_signed_char
+unsigned char explicit_cppstyleunsigned_char_to_signed_char(unsigned char src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return static_cast<unsigned char>(src);
+}
+
+// CHECK-LABEL: @explicit_cppstylesigned_char_to_signed_char
+signed char explicit_cppstylesigned_char_to_signed_char(signed char src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return static_cast<signed char>(src);
+}
+
+} // extern "C"
+
+// ---------------------------------------------------------------------------//
+// A problematic true-negative involving simple C++ code.
+// The problem is tha the NoOp ExplicitCast is directly within MaterializeTemporaryExpr(),
+// so a special care is neeeded.
+// See https://reviews.llvm.org/D48958#1161345
+template <typename a>
+a b(a c, const a &d) {
+ if (d)
+ ;
+ return c;
+}
+
+extern "C" { // Disable name mangling.
+
+// CHECK-LABEL: @false_positive_with_MaterializeTemporaryExpr
+int false_positive_with_MaterializeTemporaryExpr() {
+ // CHECK-SANITIZE-NOT: call{{.*}}ubsan
+ // CHECK: }
+ int e = b<unsigned>(4, static_cast<unsigned>(4294967296));
+ return e;
+}
+
+// ---------------------------------------------------------------------------//
+
+} // extern "C"
diff --git a/src/llvm-project/clang/test/CodeGenCXX/catch-undef-behavior.cpp b/src/llvm-project/clang/test/CodeGenCXX/catch-undef-behavior.cpp
new file mode 100644
index 0000000..0e8d4fa
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/catch-undef-behavior.cpp
@@ -0,0 +1,685 @@
+// RUN: %clang_cc1 -std=c++11 -fsanitize=signed-integer-overflow,integer-divide-by-zero,float-divide-by-zero,shift-base,shift-exponent,unreachable,return,vla-bound,alignment,null,vptr,object-size,float-cast-overflow,bool,enum,array-bounds,function -fsanitize-recover=signed-integer-overflow,integer-divide-by-zero,float-divide-by-zero,shift-base,shift-exponent,vla-bound,alignment,null,vptr,object-size,float-cast-overflow,bool,enum,array-bounds,function -emit-llvm %s -o - -triple x86_64-linux-gnu | opt -instnamer -S | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -fsanitize=vptr,address -fsanitize-recover=vptr,address -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK-ASAN
+// RUN: %clang_cc1 -std=c++11 -fsanitize=vptr -fsanitize-recover=vptr -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=DOWNCAST-NULL
+// RUN: %clang_cc1 -std=c++11 -fsanitize=function -emit-llvm %s -o - -triple x86_64-linux-gnux32 | FileCheck %s --check-prefix=CHECK-X32
+// RUN: %clang_cc1 -std=c++11 -fsanitize=function -emit-llvm %s -o - -triple i386-linux-gnu | FileCheck %s --check-prefix=CHECK-X86
+
+struct S {
+ double d;
+ int a, b;
+ virtual int f();
+};
+
+// Check that type descriptor global is not modified by ASan.
+// CHECK-ASAN: [[TYPE_DESCR:@[0-9]+]] = private unnamed_addr constant { i16, i16, [4 x i8] } { i16 -1, i16 0, [4 x i8] c"'S'\00" }
+
+// Check that type mismatch handler is not modified by ASan.
+// CHECK-ASAN: private unnamed_addr global { { [{{.*}} x i8]*, i32, i32 }, { i16, i16, [4 x i8] }*, i8*, i8 } { {{.*}}, { i16, i16, [4 x i8] }* [[TYPE_DESCR]], {{.*}} }
+
+// CHECK: [[IndirectRTTI_ZTIFvPFviEE:@.+]] = private constant i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*)
+// CHECK-X86: [[IndirectRTTI_ZTIFvPFviEE:@.+]] = private constant i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*)
+// CHECK-X32: [[IndirectRTTI_ZTIFvPFviEE:@.+]] = private constant i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*)
+
+struct T : S {};
+
+// CHECK-LABEL: @_Z17reference_binding
+void reference_binding(int *p, S *q) {
+ // C++ core issue 453: If an lvalue to which a reference is directly bound
+ // designates neither an existing object or function of an appropriate type,
+ // nor a region of storage of suitable size and alignment to contain an object
+ // of the reference's type, the behavior is undefined.
+
+ // CHECK: icmp ne {{.*}}, null
+
+ // CHECK: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64
+ // CHECK-NEXT: icmp uge i64 %[[SIZE]], 4
+
+ // CHECK: %[[PTRINT:.*]] = ptrtoint
+ // CHECK-NEXT: %[[MISALIGN:.*]] = and i64 %[[PTRINT]], 3
+ // CHECK-NEXT: icmp eq i64 %[[MISALIGN]], 0
+ int &r = *p;
+
+ // A reference is not required to refer to an object within its lifetime.
+ // CHECK-NOT: __ubsan_handle_dynamic_type_cache_miss
+ S &r2 = *q;
+}
+
+// CHECK-LABEL: @_Z13member_access
+// CHECK-ASAN-LABEL: @_Z13member_access
+void member_access(S *p) {
+ // (1a) Check 'p' is appropriately sized and aligned for member access.
+
+ // CHECK: icmp ne {{.*}}, null
+
+ // CHECK: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64
+ // CHECK-NEXT: icmp uge i64 %[[SIZE]], 24
+
+ // CHECK: %[[PTRINT:.*]] = ptrtoint
+ // CHECK-NEXT: %[[MISALIGN:.*]] = and i64 %[[PTRINT]], 7
+ // CHECK-NEXT: icmp eq i64 %[[MISALIGN]], 0
+
+ // (1b) Check that 'p' actually points to an 'S'.
+
+ // CHECK: %[[VPTRADDR:.*]] = bitcast {{.*}} to i64*
+ // CHECK-NEXT: %[[VPTR:.*]] = load i64, i64* %[[VPTRADDR]]
+ //
+ // hash_16_bytes:
+ //
+ // If this number changes, it indicates that either the mangled name of ::S
+ // has changed, or that LLVM's hashing function has changed. The latter case
+ // is OK if the hashing function is still stable.
+ //
+ // The two hash values are for 64- and 32-bit Clang binaries, respectively.
+ // FIXME: We should produce a 64-bit value either way.
+ //
+ // CHECK-NEXT: xor i64 {{-4030275160588942838|1107558922}}, %[[VPTR]]
+ // CHECK-NEXT: mul i64 {{.*}}, -7070675565921424023
+ // CHECK-NEXT: lshr i64 {{.*}}, 47
+ // CHECK-NEXT: xor i64
+ // CHECK-NEXT: xor i64 %[[VPTR]]
+ // CHECK-NEXT: mul i64 {{.*}}, -7070675565921424023
+ // CHECK-NEXT: lshr i64 {{.*}}, 47
+ // CHECK-NEXT: xor i64
+ // CHECK-NEXT: %[[HASH:.*]] = mul i64 {{.*}}, -7070675565921424023
+ //
+ // Check the hash against the table:
+ //
+ // CHECK-NEXT: %[[IDX:.*]] = and i64 %{{.*}}, 127
+ // CHECK-NEXT: getelementptr inbounds [128 x i64], [128 x i64]* @__ubsan_vptr_type_cache, i32 0, i64 %[[IDX]]
+ // CHECK-NEXT: %[[CACHEVAL:.*]] = load i64, i64*
+ // CHECK-NEXT: icmp eq i64 %[[CACHEVAL]], %[[HASH]]
+ // CHECK-NEXT: br i1
+
+ // CHECK: call void @__ubsan_handle_dynamic_type_cache_miss({{.*}}, i64 %{{.*}}, i64 %[[HASH]])
+ // CHECK-NOT: unreachable
+ // CHECK: {{.*}}:
+
+ // (2) Check 'p->b' is appropriately sized and aligned for a load.
+
+ // FIXME: Suppress this in the trivial case of a member access, because we
+ // know we've just checked the member access expression itself.
+
+ // CHECK: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64
+ // CHECK-NEXT: icmp uge i64 %[[SIZE]], 4
+
+ // CHECK: %[[PTRINT:.*]] = ptrtoint
+ // CHECK-NEXT: %[[MISALIGN:.*]] = and i64 %[[PTRINT]], 3
+ // CHECK-NEXT: icmp eq i64 %[[MISALIGN]], 0
+ int k = p->b;
+
+ // (3a) Check 'p' is appropriately sized and aligned for member function call.
+
+ // CHECK: icmp ne {{.*}}, null
+
+ // CHECK: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64
+ // CHECK-NEXT: icmp uge i64 %[[SIZE]], 24
+
+ // CHECK: %[[PTRINT:.*]] = ptrtoint
+ // CHECK-NEXT: %[[MISALIGN:.*]] = and i64 %[[PTRINT]], 7
+ // CHECK-NEXT: icmp eq i64 %[[MISALIGN]], 0
+
+ // (3b) Check that 'p' actually points to an 'S'
+
+ // CHECK: load i64, i64*
+ // CHECK-NEXT: xor i64 {{-4030275160588942838|1107558922}},
+ // [...]
+ // CHECK: getelementptr inbounds [128 x i64], [128 x i64]* @__ubsan_vptr_type_cache, i32 0, i64 %
+ // CHECK: br i1
+ // CHECK: call void @__ubsan_handle_dynamic_type_cache_miss({{.*}}, i64 %{{.*}}, i64 %{{.*}})
+ // CHECK-NOT: unreachable
+ // CHECK: {{.*}}:
+
+ k = p->f();
+}
+
+// CHECK-LABEL: @_Z12lsh_overflow
+int lsh_overflow(int a, int b) {
+ // CHECK: %[[RHS_INBOUNDS:.*]] = icmp ule i32 %[[RHS:.*]], 31
+ // CHECK-NEXT: br i1 %[[RHS_INBOUNDS]], label %[[CHECK_BB:.*]], label %[[CONT_BB:.*]],
+
+ // CHECK: [[CHECK_BB]]:
+ // CHECK-NEXT: %[[SHIFTED_OUT_WIDTH:.*]] = sub nuw nsw i32 31, %[[RHS]]
+ // CHECK-NEXT: %[[SHIFTED_OUT:.*]] = lshr i32 %[[LHS:.*]], %[[SHIFTED_OUT_WIDTH]]
+
+ // This is present for C++11 but not for C: C++ core issue 1457 allows a '1'
+ // to be shifted into the sign bit, but not out of it.
+ // CHECK-NEXT: %[[SHIFTED_OUT_NOT_SIGN:.*]] = lshr i32 %[[SHIFTED_OUT]], 1
+
+ // CHECK-NEXT: %[[NO_OVERFLOW:.*]] = icmp eq i32 %[[SHIFTED_OUT_NOT_SIGN]], 0
+ // CHECK-NEXT: br label %[[CONT_BB]]
+
+ // CHECK: [[CONT_BB]]:
+ // CHECK-NEXT: %[[VALID_BASE:.*]] = phi i1 [ true, {{.*}} ], [ %[[NO_OVERFLOW]], %[[CHECK_BB]] ]
+ // CHECK-NEXT: %[[VALID:.*]] = and i1 %[[RHS_INBOUNDS]], %[[VALID_BASE]]
+ // CHECK-NEXT: br i1 %[[VALID]]
+
+ // CHECK: call void @__ubsan_handle_shift_out_of_bounds
+ // CHECK-NOT: call void @__ubsan_handle_shift_out_of_bounds
+
+ // CHECK: %[[RET:.*]] = shl i32 %[[LHS]], %[[RHS]]
+ // CHECK-NEXT: ret i32 %[[RET]]
+ return a << b;
+}
+
+// CHECK-LABEL: @_Z9no_return
+int no_return() {
+ // CHECK: call void @__ubsan_handle_missing_return(i8* bitcast ({{.*}}* @{{.*}} to i8*)) [[NR_NUW:#[0-9]+]]
+ // CHECK-NEXT: unreachable
+}
+
+// CHECK-LABEL: @_Z9sour_bool
+bool sour_bool(bool *p) {
+ // CHECK: %[[OK:.*]] = icmp ule i8 {{.*}}, 1
+ // CHECK: br i1 %[[OK]]
+ // CHECK: call void @__ubsan_handle_load_invalid_value(i8* bitcast ({{.*}}), i64 {{.*}})
+ return *p;
+}
+
+enum E1 { e1a = 0, e1b = 127 } e1;
+enum E2 { e2a = -1, e2b = 64 } e2;
+enum E3 { e3a = (1u << 31) - 1 } e3;
+
+// CHECK-LABEL: @_Z14bad_enum_value
+int bad_enum_value() {
+ // CHECK: %[[E1:.*]] = icmp ule i32 {{.*}}, 127
+ // CHECK: br i1 %[[E1]]
+ // CHECK: call void @__ubsan_handle_load_invalid_value(
+ int a = e1;
+
+ // CHECK: %[[E2HI:.*]] = icmp sle i32 {{.*}}, 127
+ // CHECK: %[[E2LO:.*]] = icmp sge i32 {{.*}}, -128
+ // CHECK: %[[E2:.*]] = and i1 %[[E2HI]], %[[E2LO]]
+ // CHECK: br i1 %[[E2]]
+ // CHECK: call void @__ubsan_handle_load_invalid_value(
+ int b = e2;
+
+ // CHECK: %[[E3:.*]] = icmp ule i32 {{.*}}, 2147483647
+ // CHECK: br i1 %[[E3]]
+ // CHECK: call void @__ubsan_handle_load_invalid_value(
+ int c = e3;
+ return a + b + c;
+}
+
+// CHECK-LABEL: @_Z20bad_downcast_pointer
+// DOWNCAST-NULL-LABEL: @_Z20bad_downcast_pointer
+void bad_downcast_pointer(S *p) {
+ // CHECK: %[[NONNULL:.*]] = icmp ne {{.*}}, null
+ // CHECK: br i1 %[[NONNULL]],
+
+ // A null pointer access is guarded without -fsanitize=null.
+ // DOWNCAST-NULL: %[[NONNULL:.*]] = icmp ne {{.*}}, null
+ // DOWNCAST-NULL: br i1 %[[NONNULL]],
+
+ // CHECK: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64.p0i8(
+ // CHECK: %[[E1:.*]] = icmp uge i64 %[[SIZE]], 24
+ // CHECK: %[[MISALIGN:.*]] = and i64 %{{.*}}, 7
+ // CHECK: %[[E2:.*]] = icmp eq i64 %[[MISALIGN]], 0
+ // CHECK: %[[E12:.*]] = and i1 %[[E1]], %[[E2]]
+ // CHECK: br i1 %[[E12]],
+
+ // CHECK: call void @__ubsan_handle_type_mismatch
+ // CHECK: br label
+
+ // CHECK: br i1 %{{.*}},
+
+ // CHECK: call void @__ubsan_handle_dynamic_type_cache_miss
+ // CHECK: br label
+ (void) static_cast<T*>(p);
+}
+
+// CHECK-LABEL: @_Z22bad_downcast_reference
+void bad_downcast_reference(S &p) {
+ // CHECK: %[[E1:.*]] = icmp ne {{.*}}, null
+ // CHECK-NOT: br i1
+
+ // CHECK: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64.p0i8(
+ // CHECK: %[[E2:.*]] = icmp uge i64 %[[SIZE]], 24
+
+ // CHECK: %[[MISALIGN:.*]] = and i64 %{{.*}}, 7
+ // CHECK: %[[E3:.*]] = icmp eq i64 %[[MISALIGN]], 0
+
+ // CHECK: %[[E12:.*]] = and i1 %[[E1]], %[[E2]]
+ // CHECK: %[[E123:.*]] = and i1 %[[E12]], %[[E3]]
+ // CHECK: br i1 %[[E123]],
+
+ // CHECK: call void @__ubsan_handle_type_mismatch
+ // CHECK: br label
+
+ // CHECK: br i1 %{{.*}},
+
+ // CHECK: call void @__ubsan_handle_dynamic_type_cache_miss
+ // CHECK: br label
+ (void) static_cast<T&>(p);
+}
+
+// CHECK-LABEL: @_Z11array_index
+int array_index(const int (&a)[4], int n) {
+ // CHECK: %[[K1_OK:.*]] = icmp ult i64 %{{.*}}, 4
+ // CHECK: br i1 %[[K1_OK]]
+ // CHECK: call void @__ubsan_handle_out_of_bounds(
+ int k1 = a[n];
+
+ // CHECK: %[[R1_OK:.*]] = icmp ule i64 %{{.*}}, 4
+ // CHECK: br i1 %[[R1_OK]]
+ // CHECK: call void @__ubsan_handle_out_of_bounds(
+ const int *r1 = &a[n];
+
+ // CHECK: %[[K2_OK:.*]] = icmp ult i64 %{{.*}}, 8
+ // CHECK: br i1 %[[K2_OK]]
+ // CHECK: call void @__ubsan_handle_out_of_bounds(
+ int k2 = ((const int(&)[8])a)[n];
+
+ // CHECK: %[[K3_OK:.*]] = icmp ult i64 %{{.*}}, 4
+ // CHECK: br i1 %[[K3_OK]]
+ // CHECK: call void @__ubsan_handle_out_of_bounds(
+ int k3 = n[a];
+
+ return k1 + *r1 + k2;
+}
+
+// CHECK-LABEL: @_Z17multi_array_index
+int multi_array_index(int n, int m) {
+ int arr[4][6];
+
+ // CHECK: %[[IDX1_OK:.*]] = icmp ult i64 %{{.*}}, 4
+ // CHECK: br i1 %[[IDX1_OK]]
+ // CHECK: call void @__ubsan_handle_out_of_bounds(
+
+ // CHECK: %[[IDX2_OK:.*]] = icmp ult i64 %{{.*}}, 6
+ // CHECK: br i1 %[[IDX2_OK]]
+ // CHECK: call void @__ubsan_handle_out_of_bounds(
+ return arr[n][m];
+}
+
+// CHECK-LABEL: @_Z11array_arith
+int array_arith(const int (&a)[4], int n) {
+ // CHECK: %[[K1_OK:.*]] = icmp ule i64 %{{.*}}, 4
+ // CHECK: br i1 %[[K1_OK]]
+ // CHECK: call void @__ubsan_handle_out_of_bounds(
+ const int *k1 = a + n;
+
+ // CHECK: %[[K2_OK:.*]] = icmp ule i64 %{{.*}}, 8
+ // CHECK: br i1 %[[K2_OK]]
+ // CHECK: call void @__ubsan_handle_out_of_bounds(
+ const int *k2 = (const int(&)[8])a + n;
+
+ return *k1 + *k2;
+}
+
+struct ArrayMembers {
+ int a1[5];
+ int a2[1];
+};
+// CHECK-LABEL: @_Z18struct_array_index
+int struct_array_index(ArrayMembers *p, int n) {
+ // CHECK: %[[IDX_OK:.*]] = icmp ult i64 %{{.*}}, 5
+ // CHECK: br i1 %[[IDX_OK]]
+ // CHECK: call void @__ubsan_handle_out_of_bounds(
+ return p->a1[n];
+}
+
+// CHECK-LABEL: @_Z16flex_array_index
+int flex_array_index(ArrayMembers *p, int n) {
+ // CHECK-NOT: call void @__ubsan_handle_out_of_bounds(
+ return p->a2[n];
+}
+
+extern int incomplete[];
+// CHECK-LABEL: @_Z22incomplete_array_index
+int incomplete_array_index(int n) {
+ // CHECK-NOT: call void @__ubsan_handle_out_of_bounds(
+ return incomplete[n];
+}
+
+typedef __attribute__((ext_vector_type(4))) int V4I;
+// CHECK-LABEL: @_Z12vector_index
+int vector_index(V4I v, int n) {
+ // CHECK: %[[IDX_OK:.*]] = icmp ult i64 %{{.*}}, 4
+ // CHECK: br i1 %[[IDX_OK]]
+ // CHECK: call void @__ubsan_handle_out_of_bounds(
+ return v[n];
+}
+
+// CHECK-LABEL: @_Z12string_index
+char string_index(int n) {
+ // CHECK: %[[IDX_OK:.*]] = icmp ult i64 %{{.*}}, 6
+ // CHECK: br i1 %[[IDX_OK]]
+ // CHECK: call void @__ubsan_handle_out_of_bounds(
+ return "Hello"[n];
+}
+
+class A // align=4
+{
+ int a1, a2, a3;
+};
+
+class B // align=8
+{
+ long b1, b2;
+};
+
+class C : public A, public B // align=16
+{
+ alignas(16) int c1;
+};
+
+// Make sure we check the alignment of the pointer after subtracting any
+// offset. The pointer before subtraction doesn't need to be aligned for
+// the destination type.
+
+// CHECK-LABEL: define void @_Z16downcast_pointerP1B(%class.B* %b)
+void downcast_pointer(B *b) {
+ (void) static_cast<C*>(b);
+ // Alignment check from EmitTypeCheck(TCK_DowncastPointer, ...)
+ // CHECK: [[SUB:%[.a-z0-9]*]] = getelementptr inbounds i8, i8* {{.*}}, i64 -16
+ // CHECK-NEXT: [[C:%.+]] = bitcast i8* [[SUB]] to %class.C*
+ // null check goes here
+ // CHECK: [[FROM_PHI:%.+]] = phi %class.C* [ [[C]], {{.*}} ], {{.*}}
+ // Objectsize check goes here
+ // CHECK: [[C_INT:%.+]] = ptrtoint %class.C* [[FROM_PHI]] to i64
+ // CHECK-NEXT: [[MASKED:%.+]] = and i64 [[C_INT]], 15
+ // CHECK-NEXT: [[TEST:%.+]] = icmp eq i64 [[MASKED]], 0
+ // AND the alignment test with the objectsize test.
+ // CHECK-NEXT: [[AND:%.+]] = and i1 {{.*}}, [[TEST]]
+ // CHECK-NEXT: br i1 [[AND]]
+}
+
+// CHECK-LABEL: define void @_Z18downcast_referenceR1B(%class.B* dereferenceable({{[0-9]+}}) %b)
+void downcast_reference(B &b) {
+ (void) static_cast<C&>(b);
+ // Alignment check from EmitTypeCheck(TCK_DowncastReference, ...)
+ // CHECK: [[SUB:%[.a-z0-9]*]] = getelementptr inbounds i8, i8* {{.*}}, i64 -16
+ // CHECK-NEXT: [[C:%.+]] = bitcast i8* [[SUB]] to %class.C*
+ // Objectsize check goes here
+ // CHECK: [[C_INT:%.+]] = ptrtoint %class.C* [[C]] to i64
+ // CHECK-NEXT: [[MASKED:%.+]] = and i64 [[C_INT]], 15
+ // CHECK-NEXT: [[TEST:%.+]] = icmp eq i64 [[MASKED]], 0
+ // AND the alignment test with the objectsize test.
+ // CHECK: [[AND:%.+]] = and i1 {{.*}}, [[TEST]]
+ // CHECK-NEXT: br i1 [[AND]]
+}
+
+//
+// CHECK-LABEL: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, i32 }> <{ i32 846595819, i32 trunc (i64 sub (i64 ptrtoint (i8** {{.*}} to i64), i64 ptrtoint (void (void (i32)*)* @_Z22indirect_function_callPFviE to i64)) to i32) }>
+// CHECK-X32: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, i32 }> <{ i32 846595819, i32 sub (i32 ptrtoint (i8** [[IndirectRTTI_ZTIFvPFviEE]] to i32), i32 ptrtoint (void (void (i32)*)* @_Z22indirect_function_callPFviE to i32)) }>
+// CHECK-X86: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, i32 }> <{ i32 846595819, i32 sub (i32 ptrtoint (i8** [[IndirectRTTI_ZTIFvPFviEE]] to i32), i32 ptrtoint (void (void (i32)*)* @_Z22indirect_function_callPFviE to i32)) }>
+void indirect_function_call(void (*p)(int)) {
+ // CHECK: [[PTR:%.+]] = bitcast void (i32)* {{.*}} to <{ i32, i32 }>*
+
+ // Signature check
+ // CHECK-NEXT: [[SIGPTR:%.+]] = getelementptr <{ i32, i32 }>, <{ i32, i32 }>* [[PTR]], i32 0, i32 0
+ // CHECK-NEXT: [[SIG:%.+]] = load i32, i32* [[SIGPTR]]
+ // CHECK-NEXT: [[SIGCMP:%.+]] = icmp eq i32 [[SIG]], 846595819
+ // CHECK-NEXT: br i1 [[SIGCMP]]
+
+ // RTTI pointer check
+ // CHECK: [[RTTIPTR:%.+]] = getelementptr <{ i32, i32 }>, <{ i32, i32 }>* [[PTR]], i32 0, i32 1
+ // CHECK-NEXT: [[RTTIEncIntTrunc:%.+]] = load i32, i32* [[RTTIPTR]]
+ // CHECK-NEXT: [[RTTIEncInt:%.+]] = sext i32 [[RTTIEncIntTrunc]] to i64
+ // CHECK-NEXT: [[FuncAddrInt:%.+]] = ptrtoint void (i32)* {{.*}} to i64
+ // CHECK-NEXT: [[IndirectGVInt:%.+]] = add i64 [[RTTIEncInt]], [[FuncAddrInt]]
+ // CHECK-NEXT: [[IndirectGV:%.+]] = inttoptr i64 [[IndirectGVInt]] to i8**
+ // CHECK-NEXT: [[RTTI:%.+]] = load i8*, i8** [[IndirectGV]], align 8
+ // CHECK-NEXT: [[RTTICMP:%.+]] = icmp eq i8* [[RTTI]], bitcast ({ i8*, i8* }* @_ZTIFviE to i8*)
+ // CHECK-NEXT: br i1 [[RTTICMP]]
+
+ p(42);
+}
+
+namespace FunctionSanitizerVirtualCalls {
+struct A {
+ virtual void f() {}
+ virtual void g() {}
+ void h() {}
+};
+
+struct B : virtual A {
+ virtual void b() {}
+ virtual void f();
+ void g() final {}
+ static void q() {}
+};
+
+void B::f() {}
+
+void force_irgen() {
+ A a;
+ a.g();
+ a.h();
+
+ B b;
+ b.f();
+ b.b();
+ b.g();
+ B::q();
+}
+
+// CHECK-LABEL: define void @_ZN29FunctionSanitizerVirtualCalls1B1fEv
+// CHECK-NOT: prologue
+//
+// CHECK-LABEL: define void @_ZTv0_n24_N29FunctionSanitizerVirtualCalls1B1fEv
+// CHECK-NOT: prologue
+//
+// CHECK-LABEL: define void @_ZN29FunctionSanitizerVirtualCalls11force_irgenEv()
+// CHECK: prologue
+//
+// CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1AC1Ev
+// CHECK-NOT: prologue
+//
+// CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1A1gEv
+// CHECK-NOT: prologue
+//
+// CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1A1hEv
+// CHECK-NOT: prologue
+//
+// CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1BC1Ev
+// CHECK-NOT: prologue
+//
+// CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1B1bEv
+// CHECK-NOT: prologue
+//
+// CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1B1gEv
+// CHECK-NOT: prologue
+//
+// CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1B1qEv
+// CHECK: prologue
+
+}
+
+namespace UpcastPointerTest {
+struct S {};
+struct T : S { double d; };
+struct V : virtual S {};
+
+// CHECK-LABEL: upcast_pointer
+S* upcast_pointer(T* t) {
+ // Check for null pointer
+ // CHECK: %[[NONNULL:.*]] = icmp ne {{.*}}, null
+ // CHECK: br i1 %[[NONNULL]]
+
+ // Check alignment
+ // CHECK: %[[MISALIGN:.*]] = and i64 %{{.*}}, 7
+ // CHECK: icmp eq i64 %[[MISALIGN]], 0
+
+ // CHECK: call void @__ubsan_handle_type_mismatch
+ return t;
+}
+
+V getV();
+
+// CHECK-LABEL: upcast_to_vbase
+void upcast_to_vbase() {
+ // No need to check for null here, as we have a temporary here.
+
+ // CHECK-NOT: br i1
+
+ // CHECK: call i64 @llvm.objectsize
+ // CHECK: call void @__ubsan_handle_type_mismatch
+ // CHECK: call void @__ubsan_handle_dynamic_type_cache_miss
+ const S& s = getV();
+}
+}
+
+struct nothrow {};
+void *operator new[](__SIZE_TYPE__, nothrow) noexcept;
+
+namespace NothrowNew {
+ struct X { X(); };
+
+ // CHECK-LABEL: define{{.*}}nothrow_new_trivial
+ void *nothrow_new_trivial() {
+ // CHECK: %[[is_null:.*]] = icmp eq i8*{{.*}}, null
+ // CHECK: br i1 %[[is_null]], label %[[null:.*]], label %[[nonnull:.*]]
+
+ // CHECK: [[nonnull]]:
+ // CHECK: llvm.objectsize
+ // CHECK: br i1
+ //
+ // CHECK: call {{.*}}__ubsan_handle_type_mismatch
+ //
+ // CHECK: [[null]]:
+ // CHECK-NOT: {{ }}br{{ }}
+ // CHECK: ret
+ return new (nothrow{}) char[123456];
+ }
+
+ // CHECK-LABEL: define{{.*}}nothrow_new_nontrivial
+ void *nothrow_new_nontrivial() {
+ // CHECK: %[[is_null:.*]] = icmp eq i8*{{.*}}, null
+ // CHECK: br i1 %[[is_null]], label %[[null:.*]], label %[[nonnull:.*]]
+
+ // CHECK: [[nonnull]]:
+ // CHECK: llvm.objectsize
+ // CHECK: br i1
+ //
+ // CHECK: call {{.*}}__ubsan_handle_type_mismatch
+ //
+ // CHECK: call {{.*}}_ZN10NothrowNew1XC1Ev
+ //
+ // CHECK: [[null]]:
+ // CHECK-NOT: {{ }}br{{ }}
+ // CHECK: ret
+ return new (nothrow{}) X[123456];
+ }
+}
+
+struct ThisAlign {
+ void this_align_lambda();
+ void this_align_lambda_2();
+};
+void ThisAlign::this_align_lambda() {
+ // CHECK-LABEL: define internal %struct.ThisAlign* @"_ZZN9ThisAlign17this_align_lambdaEvENK3$_0clEv"
+ // CHECK-SAME: (%{{.*}}* %[[this:[^)]*]])
+ // CHECK: %[[this_addr:.*]] = alloca
+ // CHECK: store %{{.*}}* %[[this]], %{{.*}}** %[[this_addr]],
+ // CHECK: %[[this_inner:.*]] = load %{{.*}}*, %{{.*}}** %[[this_addr]],
+ // CHECK: %[[this_outer_addr:.*]] = getelementptr inbounds %{{.*}}, %{{.*}}* %[[this_inner]], i32 0, i32 0
+ // CHECK: %[[this_outer:.*]] = load %{{.*}}*, %{{.*}}** %[[this_outer_addr]],
+ //
+ // CHECK: %[[this_inner_isnonnull:.*]] = icmp ne %{{.*}}* %[[this_inner]], null
+ // CHECK: %[[this_inner_asint:.*]] = ptrtoint %{{.*}}* %[[this_inner]] to i
+ // CHECK: %[[this_inner_misalignment:.*]] = and i{{32|64}} %[[this_inner_asint]], {{3|7}},
+ // CHECK: %[[this_inner_isaligned:.*]] = icmp eq i{{32|64}} %[[this_inner_misalignment]], 0
+ // CHECK: %[[this_inner_valid:.*]] = and i1 %[[this_inner_isnonnull]], %[[this_inner_isaligned]],
+ // CHECK: br i1 %[[this_inner_valid:.*]]
+ [&] { return this; } ();
+}
+
+namespace CopyValueRepresentation {
+ // CHECK-LABEL: define {{.*}} @_ZN23CopyValueRepresentation2S3aSERKS0_
+ // CHECK-NOT: call {{.*}} @__ubsan_handle_load_invalid_value
+ // CHECK-LABEL: define {{.*}} @_ZN23CopyValueRepresentation2S4aSEOS0_
+ // CHECK-NOT: call {{.*}} @__ubsan_handle_load_invalid_value
+ // CHECK-LABEL: define {{.*}} @_ZN23CopyValueRepresentation2S1C2ERKS0_
+ // CHECK-NOT: call {{.*}} __ubsan_handle_load_invalid_value
+ // CHECK-LABEL: define {{.*}} @_ZN23CopyValueRepresentation2S2C2ERKS0_
+ // CHECK: __ubsan_handle_load_invalid_value
+ // CHECK-LABEL: define {{.*}} @_ZN23CopyValueRepresentation2S5C2ERKS0_
+ // CHECK-NOT: call {{.*}} __ubsan_handle_load_invalid_value
+
+ struct CustomCopy { CustomCopy(); CustomCopy(const CustomCopy&); };
+ struct S1 {
+ CustomCopy CC;
+ bool b;
+ };
+ void callee1(S1);
+ void test1() {
+ S1 s11;
+ callee1(s11);
+ S1 s12;
+ s12 = s11;
+ }
+
+ static bool some_global_bool;
+ struct ExprCopy {
+ ExprCopy();
+ ExprCopy(const ExprCopy&, bool b = some_global_bool);
+ };
+ struct S2 {
+ ExprCopy EC;
+ bool b;
+ };
+ void callee2(S2);
+ void test2(void) {
+ S2 s21;
+ callee2(s21);
+ S2 s22;
+ s22 = s21;
+ }
+
+ struct CustomAssign { CustomAssign &operator=(const CustomAssign&); };
+ struct S3 {
+ CustomAssign CA;
+ bool b;
+ };
+ void test3() {
+ S3 x, y;
+ x = y;
+ }
+
+ struct CustomMove {
+ CustomMove();
+ CustomMove(const CustomMove&&);
+ CustomMove &operator=(const CustomMove&&);
+ };
+ struct S4 {
+ CustomMove CM;
+ bool b;
+ };
+ void test4() {
+ S4 x, y;
+ x = static_cast<S4&&>(y);
+ }
+
+ struct EnumCustomCopy {
+ EnumCustomCopy();
+ EnumCustomCopy(const EnumCustomCopy&);
+ };
+ struct S5 {
+ EnumCustomCopy ECC;
+ bool b;
+ };
+ void callee5(S5);
+ void test5() {
+ S5 s51;
+ callee5(s51);
+ S5 s52;
+ s52 = s51;
+ }
+}
+
+void ThisAlign::this_align_lambda_2() {
+ // CHECK-LABEL: define internal void @"_ZZN9ThisAlign19this_align_lambda_2EvENK3$_1clEv"
+ // CHECK-SAME: (%{{.*}}* %[[this:[^)]*]])
+ // CHECK: %[[this_addr:.*]] = alloca
+ // CHECK: store %{{.*}}* %[[this]], %{{.*}}** %[[this_addr]],
+ // CHECK: %[[this_inner:.*]] = load %{{.*}}*, %{{.*}}** %[[this_addr]],
+ //
+ // Do not perform a null check on the 'this' pointer if the function might be
+ // called from a static invoker.
+ // CHECK-NOT: icmp ne %{{.*}}* %[[this_inner]], null
+ auto *p = +[] {};
+ p();
+}
+
+// CHECK: attributes [[NR_NUW]] = { noreturn nounwind }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/catch-undef-behavior2.cpp b/src/llvm-project/clang/test/CodeGenCXX/catch-undef-behavior2.cpp
new file mode 100644
index 0000000..6e9ca0c
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/catch-undef-behavior2.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -std=c++11 -fsanitize=signed-integer-overflow,integer-divide-by-zero,float-divide-by-zero,shift-base,shift-exponent,unreachable,return,vla-bound,alignment,null,vptr,object-size,float-cast-overflow,bool,enum,array-bounds,function -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s
+
+bool GetOptionalBool(bool *value);
+bool GetBool(bool default_value) {
+ // CHECK-LABEL: @_Z7GetBoolb
+ // CHECK-NOT: select
+ bool value;
+ return GetOptionalBool(&value) ? value : default_value;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cfi-blacklist.cpp b/src/llvm-project/clang/test/CodeGenCXX/cfi-blacklist.cpp
new file mode 100644
index 0000000..c01e5fc
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cfi-blacklist.cpp
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -fvisibility hidden -fms-extensions -fsanitize=cfi-vcall -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=NOBL %s
+
+// Check that blacklisting cfi and cfi-vcall work correctly
+// RUN: echo "[cfi-vcall]" > %t.vcall.txt
+// RUN: echo "type:std::*" >> %t.vcall.txt
+// RUN: %clang_cc1 -triple %itanium_abi_triple -fvisibility hidden -fms-extensions -fsanitize=cfi-vcall -fsanitize-blacklist=%t.vcall.txt -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=NOSTD %s
+//
+// RUN: echo "[cfi]" > %t.cfi.txt
+// RUN: echo "type:std::*" >> %t.cfi.txt
+// RUN: %clang_cc1 -triple %itanium_abi_triple -fvisibility hidden -fms-extensions -fsanitize=cfi-vcall -fsanitize-blacklist=%t.cfi.txt -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=NOSTD %s
+
+// Check that blacklisting non-vcall modes does not affect vcalls
+// RUN: echo "[cfi-icall|cfi-nvcall|cfi-cast-strict|cfi-derived-cast|cfi-unrelated-cast]" > %t.other.txt
+// RUN: echo "type:std::*" >> %t.other.txt
+// RUN: %clang_cc1 -triple %itanium_abi_triple -fvisibility hidden -fms-extensions -fsanitize=cfi-vcall -fsanitize-blacklist=%t.other.txt -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=NOBL %s
+
+struct S1 {
+ virtual void f();
+};
+
+namespace std {
+
+struct S2 {
+ virtual void f();
+};
+
+}
+
+// CHECK: define{{.*}}s1f
+// NOBL: llvm.type.test
+// NOSTD: llvm.type.test
+void s1f(S1 *s1) {
+ s1->f();
+}
+
+// CHECK: define{{.*}}s2f
+// NOBL: llvm.type.test
+// NOSTD-NOT: llvm.type.test
+void s2f(std::S2 *s2) {
+ s2->f();
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cfi-cast.cpp b/src/llvm-project/clang/test/CodeGenCXX/cfi-cast.cpp
new file mode 100644
index 0000000..54641b5
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cfi-cast.cpp
@@ -0,0 +1,134 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux -fvisibility hidden -std=c++11 -fsanitize=cfi-derived-cast -fsanitize-trap=cfi-derived-cast -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-DCAST %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux -fvisibility hidden -std=c++11 -fsanitize=cfi-unrelated-cast -fsanitize-trap=cfi-unrelated-cast -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-UCAST %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux -fvisibility hidden -std=c++11 -fsanitize=cfi-unrelated-cast,cfi-cast-strict -fsanitize-trap=cfi-unrelated-cast,cfi-cast-strict -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-UCAST-STRICT %s
+
+// In this test the main thing we are searching for is something like
+// 'metadata !"1B"' where "1B" is the mangled name of the class we are
+// casting to (or maybe its base class in non-strict mode).
+
+struct A {
+ virtual void f();
+ int i() const;
+};
+
+struct B : A {
+ virtual void f();
+};
+
+struct C : A {};
+
+// CHECK-DCAST-LABEL: define hidden void @_Z3abpP1A
+void abp(A *a) {
+ // CHECK-DCAST: [[P:%[^ ]*]] = call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1B")
+ // CHECK-DCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ,]*]]
+
+ // CHECK-DCAST: [[TRAPBB]]
+ // CHECK-DCAST-NEXT: call void @llvm.trap()
+ // CHECK-DCAST-NEXT: unreachable
+
+ // CHECK-DCAST: [[CONTBB]]
+ // CHECK-DCAST: ret
+ (void)static_cast<B*>(a);
+}
+
+// CHECK-DCAST-LABEL: define hidden void @_Z3abrR1A
+void abr(A &a) {
+ // CHECK-DCAST: [[P:%[^ ]*]] = call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1B")
+ // CHECK-DCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ,]*]]
+
+ // CHECK-DCAST: [[TRAPBB]]
+ // CHECK-DCAST-NEXT: call void @llvm.trap()
+ // CHECK-DCAST-NEXT: unreachable
+
+ // CHECK-DCAST: [[CONTBB]]
+ // CHECK-DCAST: ret
+ (void)static_cast<B&>(a);
+}
+
+// CHECK-DCAST-LABEL: define hidden void @_Z4abrrO1A
+void abrr(A &&a) {
+ // CHECK-DCAST: [[P:%[^ ]*]] = call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1B")
+ // CHECK-DCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ,]*]]
+
+ // CHECK-DCAST: [[TRAPBB]]
+ // CHECK-DCAST-NEXT: call void @llvm.trap()
+ // CHECK-DCAST-NEXT: unreachable
+
+ // CHECK-DCAST: [[CONTBB]]
+ // CHECK-DCAST: ret
+ (void)static_cast<B&&>(a);
+}
+
+// CHECK-UCAST-LABEL: define hidden void @_Z3vbpPv
+void vbp(void *p) {
+ // CHECK-UCAST: [[P:%[^ ]*]] = call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1B")
+ // CHECK-UCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ,]*]]
+
+ // CHECK-UCAST: [[TRAPBB]]
+ // CHECK-UCAST-NEXT: call void @llvm.trap()
+ // CHECK-UCAST-NEXT: unreachable
+
+ // CHECK-UCAST: [[CONTBB]]
+ // CHECK-UCAST: ret
+ (void)static_cast<B*>(p);
+}
+
+// CHECK-UCAST-LABEL: define hidden void @_Z3vbrRc
+void vbr(char &r) {
+ // CHECK-UCAST: [[P:%[^ ]*]] = call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1B")
+ // CHECK-UCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ,]*]]
+
+ // CHECK-UCAST: [[TRAPBB]]
+ // CHECK-UCAST-NEXT: call void @llvm.trap()
+ // CHECK-UCAST-NEXT: unreachable
+
+ // CHECK-UCAST: [[CONTBB]]
+ // CHECK-UCAST: ret
+ (void)reinterpret_cast<B&>(r);
+}
+
+// CHECK-UCAST-LABEL: define hidden void @_Z4vbrrOc
+void vbrr(char &&r) {
+ // CHECK-UCAST: [[P:%[^ ]*]] = call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1B")
+ // CHECK-UCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ,]*]]
+
+ // CHECK-UCAST: [[TRAPBB]]
+ // CHECK-UCAST-NEXT: call void @llvm.trap()
+ // CHECK-UCAST-NEXT: unreachable
+
+ // CHECK-UCAST: [[CONTBB]]
+ // CHECK-UCAST: ret
+ (void)reinterpret_cast<B&&>(r);
+}
+
+// CHECK-UCAST-LABEL: define hidden void @_Z3vcpPv
+// CHECK-UCAST-STRICT-LABEL: define hidden void @_Z3vcpPv
+void vcp(void *p) {
+ // CHECK-UCAST: call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1A")
+ // CHECK-UCAST-STRICT: call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1C")
+ (void)static_cast<C*>(p);
+}
+
+// CHECK-UCAST-LABEL: define hidden void @_Z3bcpP1B
+// CHECK-UCAST-STRICT-LABEL: define hidden void @_Z3bcpP1B
+void bcp(B *p) {
+ // CHECK-UCAST: call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1A")
+ // CHECK-UCAST-STRICT: call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1C")
+ (void)(C *)p;
+}
+
+// CHECK-UCAST-LABEL: define hidden void @_Z8bcp_callP1B
+// CHECK-UCAST-STRICT-LABEL: define hidden void @_Z8bcp_callP1B
+void bcp_call(B *p) {
+ // CHECK-UCAST: call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1A")
+ // CHECK-UCAST-STRICT: call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1C")
+ ((C *)p)->f();
+}
+
+// CHECK-UCAST-LABEL: define hidden i32 @_Z6a_callP1A
+// CHECK-UCAST-STRICT-LABEL: define hidden i32 @_Z6a_callP1A
+int a_call(A *a) {
+ // CHECK-UCAST-NOT: @llvm.type.test
+ // CHECK-UCAST-STRICT-NOT: @llvm.type.test
+ return a->i();
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cfi-cross-dso.cpp b/src/llvm-project/clang/test/CodeGenCXX/cfi-cross-dso.cpp
new file mode 100644
index 0000000..4b7b3d7
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cfi-cross-dso.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -flto -triple x86_64-unknown-linux -fsanitize=cfi-vcall -fsanitize-cfi-cross-dso -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=ITANIUM %s
+// RUN: %clang_cc1 -flto -triple x86_64-pc-windows-msvc -fsanitize=cfi-vcall -fsanitize-cfi-cross-dso -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=MS %s
+
+struct A {
+ A();
+ virtual void f();
+};
+
+A::A() {}
+void A::f() {}
+
+void caller(A* a) {
+ a->f();
+}
+
+namespace {
+struct B {
+ virtual void f();
+};
+
+void B::f() {}
+} // namespace
+
+void g() {
+ B b;
+ b.f();
+}
+
+// MS: @[[B_VTABLE:.*]] = private unnamed_addr constant { [2 x i8*] } {{.*}}@"??_R4B@?A0x{{[^@]*}}@@6B@"{{.*}}@"?f@B@?A0x{{[^@]*}}@@UEAAXXZ"
+
+// CHECK: %[[VT:.*]] = load void (%struct.A*)**, void (%struct.A*)***
+// CHECK: %[[VT2:.*]] = bitcast {{.*}}%[[VT]] to i8*, !nosanitize
+// ITANIUM: %[[TEST:.*]] = call i1 @llvm.type.test(i8* %[[VT2]], metadata !"_ZTS1A"), !nosanitize
+// MS: %[[TEST:.*]] = call i1 @llvm.type.test(i8* %[[VT2]], metadata !"?AUA@@"), !nosanitize
+// CHECK: br i1 %[[TEST]], label %[[CONT:.*]], label %[[SLOW:.*]], {{.*}} !nosanitize
+// CHECK: [[SLOW]]
+// ITANIUM: call void @__cfi_slowpath_diag(i64 7004155349499253778, i8* %[[VT2]], {{.*}}) {{.*}} !nosanitize
+// MS: call void @__cfi_slowpath_diag(i64 -8005289897957287421, i8* %[[VT2]], {{.*}}) {{.*}} !nosanitize
+// CHECK: br label %[[CONT]], !nosanitize
+// CHECK: [[CONT]]
+// CHECK: call void %{{.*}}(%struct.A* %{{.*}})
+
+// No hash-based bit set entry for (anonymous namespace)::B
+// ITANIUM-NOT: !{i64 {{.*}}, [3 x i8*]* @_ZTVN12_GLOBAL__N_11BE,
+// MS-NOT: !{i64 {{.*}}, [2 x i8*]* @[[B_VTABLE]],
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cfi-icall.cpp b/src/llvm-project/clang/test/CodeGenCXX/cfi-icall.cpp
new file mode 100644
index 0000000..00c9f59
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cfi-icall.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-icall -fsanitize-trap=cfi-icall -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=ITANIUM %s
+// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc -fsanitize=cfi-icall -fsanitize-trap=cfi-icall -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=MS %s
+
+// Tests that we assign unnamed metadata nodes to functions whose types have
+// internal linkage.
+
+namespace {
+
+struct S {};
+
+void f(S s) {
+}
+
+}
+
+void g() {
+ struct S s;
+ void (*fp)(S) = f;
+ // CHECK: call i1 @llvm.type.test(i8* {{.*}}, metadata [[VOIDS1:![0-9]+]])
+ fp(s);
+}
+
+// ITANIUM: define internal void @_ZN12_GLOBAL__N_11fENS_1SE({{.*}} !type [[TS1:![0-9]+]] !type [[TS2:![0-9]+]]
+// MS: define internal void @"?f@?A0x{{[^@]*}}@@YAXUS@?A0x{{[^@]*}}@@@Z"({{.*}} !type [[TS1:![0-9]+]] !type [[TS2:![0-9]+]]
+
+// CHECK: [[VOIDS1]] = distinct !{}
+// CHECK: [[TS1]] = !{i64 0, [[VOIDS1]]}
+// CHECK: [[TS2]] = !{i64 0, [[VOIDS2:![0-9]+]]}
+// CHECK: [[VOIDS2]] = distinct !{}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cfi-mfcall-incomplete.cpp b/src/llvm-project/clang/test/CodeGenCXX/cfi-mfcall-incomplete.cpp
new file mode 100644
index 0000000..345be12
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cfi-mfcall-incomplete.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-mfcall -fsanitize-trap=cfi-mfcall -fvisibility hidden -emit-llvm -o - %s | FileCheck %s
+
+struct S;
+
+void f(S *s, void (S::*p)()) {
+ // CHECK-NOT: llvm.type.test
+ // CHECK: llvm.type.test{{.*}}!"_ZTSM1SFvvE.virtual"
+ // CHECK-NOT: llvm.type.test
+ (s->*p)();
+}
+
+// CHECK: declare i1 @llvm.type.test
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cfi-mfcall.cpp b/src/llvm-project/clang/test/CodeGenCXX/cfi-mfcall.cpp
new file mode 100644
index 0000000..c16b20b
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cfi-mfcall.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-mfcall -fsanitize-trap=cfi-mfcall -fvisibility hidden -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-mfcall -fsanitize-trap=cfi-mfcall -fvisibility default -emit-llvm -o - %s | FileCheck --check-prefix=DEFAULT %s
+
+struct B1 {};
+struct B2 {};
+struct B3 : B2 {};
+struct S : B1, B3 {};
+
+// DEFAULT-NOT: llvm.type.test
+
+void f(S *s, void (S::*p)()) {
+ // CHECK: [[OFFSET:%.*]] = sub i64 {{.*}}, 1
+ // CHECK: [[VFPTR:%.*]] = getelementptr i8, i8* %{{.*}}, i64 [[OFFSET]]
+ // CHECK: [[TT:%.*]] = call i1 @llvm.type.test(i8* [[VFPTR]], metadata !"_ZTSM1SFvvE.virtual")
+ // CHECK: br i1 [[TT]], label {{.*}}, label %[[TRAP1:[^,]*]]
+
+ // CHECK: [[TRAP1]]:
+ // CHECK-NEXT: llvm.trap
+
+ // CHECK: [[NVFPTR:%.*]] = bitcast void (%struct.S*)* {{.*}} to i8*
+ // CHECK: [[TT1:%.*]] = call i1 @llvm.type.test(i8* [[NVFPTR]], metadata !"_ZTSM2B1FvvE")
+ // CHECK: [[OR1:%.*]] = or i1 false, [[TT1]]
+ // CHECK: [[TT2:%.*]] = call i1 @llvm.type.test(i8* [[NVFPTR]], metadata !"_ZTSM2B2FvvE")
+ // CHECK: [[OR2:%.*]] = or i1 [[OR1]], [[TT2]]
+ // CHECK: br i1 [[OR2]], label {{.*}}, label %[[TRAP2:[^,]*]]
+
+ // CHECK: [[TRAP2]]:
+ // CHECK-NEXT: llvm.trap
+ (s->*p)();
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cfi-ms-rtti.cpp b/src/llvm-project/clang/test/CodeGenCXX/cfi-ms-rtti.cpp
new file mode 100644
index 0000000..328297d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cfi-ms-rtti.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -flto -flto-unit -emit-llvm -o - -triple=x86_64-pc-win32 %s -fsanitize=cfi-vcall | FileCheck --check-prefix=RTTI %s
+// RUN: %clang_cc1 -flto -flto-unit -emit-llvm -o - -triple=x86_64-pc-win32 %s -fsanitize=cfi-vcall -fno-rtti-data | FileCheck --check-prefix=NO-RTTI %s
+
+struct A {
+ A();
+ virtual void f() {}
+};
+
+A::A() {}
+
+// RTTI: !{i64 8, !"?AUA@@"}
+// NO-RTTI: !{i64 0, !"?AUA@@"}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cfi-ms-vbase-derived-cast.cpp b/src/llvm-project/clang/test/CodeGenCXX/cfi-ms-vbase-derived-cast.cpp
new file mode 100644
index 0000000..6142ca5
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cfi-ms-vbase-derived-cast.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -flto -flto-unit -emit-llvm -o - -triple=x86_64-pc-win32 %s -fsanitize=cfi-derived-cast -fsanitize-trap=cfi-derived-cast | FileCheck %s
+
+struct foo {
+ virtual ~foo() {}
+ virtual void f() = 0;
+};
+
+template <typename T>
+struct bar : virtual public foo {
+ void f() {
+ // CHECK: define{{.*}}@"?f@?$bar@Ubaz@@@@UEAAXXZ"
+ // Load "this", vbtable, vbase offset and vtable.
+ // CHECK: load
+ // CHECK: load
+ // CHECK: load
+ // CHECK: load
+ // CHECK: @llvm.type.test{{.*}}!"?AUfoo@@"
+ static_cast<T&>(*this);
+ }
+};
+
+struct baz : public bar<baz> {
+ virtual ~baz() {}
+};
+
+int main() {
+ baz *z = new baz;
+ z->f();
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cfi-ms-vbase-nvcall.cpp b/src/llvm-project/clang/test/CodeGenCXX/cfi-ms-vbase-nvcall.cpp
new file mode 100644
index 0000000..d423255
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cfi-ms-vbase-nvcall.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -flto -flto-unit -emit-llvm -o - -triple=x86_64-pc-win32 %s -fsanitize=cfi-nvcall -fsanitize-trap=cfi-nvcall | FileCheck %s
+
+struct foo {
+ virtual ~foo() {}
+ virtual void f() = 0;
+};
+
+template <typename T>
+struct bar : virtual public foo {
+ void f() {}
+};
+
+struct baz : public bar<baz> {
+ virtual ~baz() {}
+ void g() {}
+};
+
+void f(baz *z) {
+ // CHECK: define{{.*}}@"?f@@YAXPEAUbaz@@@Z"
+ // Load z, vbtable, vbase offset and vtable.
+ // CHECK: load
+ // CHECK: load
+ // CHECK: load
+ // CHECK: load
+ // CHECK: @llvm.type.test{{.*}}!"?AUfoo@@"
+ z->g();
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cfi-nvcall.cpp b/src/llvm-project/clang/test/CodeGenCXX/cfi-nvcall.cpp
new file mode 100644
index 0000000..e968f05
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cfi-nvcall.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux -fvisibility hidden -fsanitize=cfi-nvcall -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux -fvisibility hidden -fsanitize=cfi-nvcall,cfi-cast-strict -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-STRICT %s
+
+struct A {
+ virtual void f();
+};
+
+struct B : A {
+ int i;
+ void g();
+};
+
+struct C : A {
+ void g();
+};
+
+// CHECK-LABEL: @bg
+// CHECK-STRICT-LABEL: @bg
+extern "C" void bg(B *b) {
+ // CHECK: call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1B")
+ // CHECK-STRICT: call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1B")
+ b->g();
+}
+
+// CHECK-LABEL: @cg
+// CHECK-STRICT-LABEL: @cg
+extern "C" void cg(C *c) {
+ // http://clang.llvm.org/docs/ControlFlowIntegrity.html#strictness
+ // In this case C's layout is the same as its base class, so we allow
+ // c to be of type A in non-strict mode.
+
+ // CHECK: call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1A")
+ // CHECK-STRICT: call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1C")
+ c->g();
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cfi-speculative-vtable.cpp b/src/llvm-project/clang/test/CodeGenCXX/cfi-speculative-vtable.cpp
new file mode 100644
index 0000000..490190c
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cfi-speculative-vtable.cpp
@@ -0,0 +1,14 @@
+// Test that we don't emit a bit set entry for a speculative (available_externally) vtable.
+// This does not happen in the Microsoft ABI.
+// RUN: %clang_cc1 -triple x86_64-unknown-linux -O1 -fsanitize=cfi-vcall -fsanitize-trap=cfi-vcall -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux -O1 -fsanitize=cfi-vcall -fsanitize-trap=cfi-vcall -fsanitize-cfi-cross-dso -emit-llvm -o - %s | FileCheck %s
+
+class A {
+ public:
+ virtual ~A();
+};
+
+A a;
+
+// CHECK: @_ZTV1A ={{.*}} available_externally
+// CHECK-NOT: !{{.*}} = !{!{{.*}}, [4 x i8*]* @_ZTV1A, i64 16}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cfi-stats.cpp b/src/llvm-project/clang/test/CodeGenCXX/cfi-stats.cpp
new file mode 100644
index 0000000..6d0dd5b
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cfi-stats.cpp
@@ -0,0 +1,51 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux -fvisibility hidden -fsanitize=cfi-vcall,cfi-nvcall,cfi-derived-cast,cfi-unrelated-cast,cfi-icall -fsanitize-stats -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux -fvisibility hidden -fsanitize=cfi-vcall,cfi-nvcall,cfi-derived-cast,cfi-unrelated-cast,cfi-icall -fsanitize-trap=cfi-vcall -fwhole-program-vtables -fsanitize-stats -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: [[STATS:@[^ ]*]] = internal global { i8*, i32, [5 x [2 x i8*]] } { i8* null, i32 5, [5 x [2 x i8*]]
+// CHECK: {{\[\[}}2 x i8*] zeroinitializer,
+// CHECK: [2 x i8*] [i8* null, i8* inttoptr (i64 2305843009213693952 to i8*)],
+// CHECK: [2 x i8*] [i8* null, i8* inttoptr (i64 4611686018427387904 to i8*)],
+// CHECK: [2 x i8*] [i8* null, i8* inttoptr (i64 6917529027641081856 to i8*)],
+// CHECK: [2 x i8*] [i8* null, i8* inttoptr (i64 -9223372036854775808 to i8*)]] }
+
+// CHECK: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 0, void ()* [[CTOR:@[^ ]*]], i8* null }]
+
+struct A {
+ virtual void vf();
+ void nvf();
+};
+struct B : A {};
+
+// CHECK: @vcall
+extern "C" void vcall(A *a) {
+ // CHECK: call void @__sanitizer_stat_report({{.*}}[[STATS]]{{.*}}i64 0, i32 2, i64 0
+ a->vf();
+}
+
+// CHECK: @nvcall
+extern "C" void nvcall(A *a) {
+ // CHECK: call void @__sanitizer_stat_report({{.*}}[[STATS]]{{.*}}i64 0, i32 2, i64 1
+ a->nvf();
+}
+
+// CHECK: @dcast
+extern "C" void dcast(A *a) {
+ // CHECK: call void @__sanitizer_stat_report({{.*}}[[STATS]]{{.*}}i64 0, i32 2, i64 2
+ static_cast<B *>(a);
+}
+
+// CHECK: @ucast
+extern "C" void ucast(void *a) {
+ // CHECK: call void @__sanitizer_stat_report({{.*}}[[STATS]]{{.*}}i64 0, i32 2, i64 3
+ reinterpret_cast<A *>(a);
+}
+
+// CHECK: @icall
+extern "C" void icall(void (*p)()) {
+ // CHECK: call void @__sanitizer_stat_report({{.*}}[[STATS]]{{.*}}i64 0, i32 2, i64 4
+ p();
+}
+
+// CHECK: define internal void [[CTOR]]()
+// CHECK-NEXT: call void @__sanitizer_stat_init(i8* bitcast ({ i8*, i32, [5 x [2 x i8*]] }* [[STATS]] to i8*))
+// CHECK-NEXT: ret void
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cfi-vcall-check-after-args.cpp b/src/llvm-project/clang/test/CodeGenCXX/cfi-vcall-check-after-args.cpp
new file mode 100644
index 0000000..4c2ea8c
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cfi-vcall-check-after-args.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -flto -flto-unit -triple x86_64-unknown-linux -fvisibility hidden -fsanitize=cfi-vcall -fsanitize-trap=cfi-vcall -emit-llvm -o - %s | FileCheck %s
+
+struct A {
+ virtual void f(int);
+};
+
+int g();
+void f(A *a) {
+ // CHECK: call i32 @_Z1gv()
+ // CHECK: call i1 @llvm.type.test
+ a->f(g());
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cfi-vcall-no-trap.cpp b/src/llvm-project/clang/test/CodeGenCXX/cfi-vcall-no-trap.cpp
new file mode 100644
index 0000000..b7ef142
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cfi-vcall-no-trap.cpp
@@ -0,0 +1,15 @@
+// Only output llvm.assume(llvm.type.test()) if cfi-vcall is disabled and whole-program-vtables is enabled
+// RUN: %clang_cc1 -flto -fvisibility hidden -fsanitize=cfi-vcall -fwhole-program-vtables -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=CFI %s
+// RUN: %clang_cc1 -flto -fvisibility hidden -fwhole-program-vtables -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=NOCFI %s
+
+struct S1 {
+ virtual void f();
+};
+
+// CHECK: define{{.*}}s1f
+// CHECK: llvm.type.test
+// CFI-NOT: llvm.assume
+// NOCFI: llvm.assume
+void s1f(S1 *s1) {
+ s1->f();
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/char8_t.cpp b/src/llvm-project/clang/test/CodeGenCXX/char8_t.cpp
new file mode 100644
index 0000000..f24f12d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/char8_t.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -std=c++17 -emit-llvm -fchar8_t -triple x86_64-linux %s -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++17 -emit-llvm -fchar8_t -triple x86_64-windows %s -o - -verify
+
+// CHECK: define void @_Z1fDu(
+void f(char8_t c) {} // expected-error {{cannot mangle this built-in char8_t type yet}}
+
+// CHECK: define weak_odr void @_Z1gIiEvDTplplcvT__ELA4_KDuELDu114EE
+template<typename T> void g(decltype(T() + u8"foo" + u8'r')) {}
+template void g<int>(const char8_t*);
diff --git a/src/llvm-project/clang/test/CodeGenCXX/clang-abi-compat.cpp b/src/llvm-project/clang/test/CodeGenCXX/clang-abi-compat.cpp
new file mode 100644
index 0000000..409c721
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/clang-abi-compat.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -std=c++17 -triple x86_64-linux-gnu -fclang-abi-compat=3.0 %s -emit-llvm -o - | FileCheck --check-prefix=PRE39 --check-prefix=PRE5 %s
+// RUN: %clang_cc1 -std=c++17 -triple x86_64-linux-gnu -fclang-abi-compat=3.8 %s -emit-llvm -o - | FileCheck --check-prefix=PRE39 --check-prefix=PRE5 %s
+// RUN: %clang_cc1 -std=c++17 -triple x86_64-linux-gnu -fclang-abi-compat=3.9 %s -emit-llvm -o - | FileCheck --check-prefix=V39 --check-prefix=PRE5 %s
+// RUN: %clang_cc1 -std=c++17 -triple x86_64-linux-gnu -fclang-abi-compat=4.0 %s -emit-llvm -o - | FileCheck --check-prefix=V39 --check-prefix=PRE5 %s
+// RUN: %clang_cc1 -std=c++17 -triple x86_64-linux-gnu -fclang-abi-compat=5 %s -emit-llvm -o - | FileCheck --check-prefix=V39 --check-prefix=V5 %s
+// RUN: %clang_cc1 -std=c++17 -triple x86_64-linux-gnu -fclang-abi-compat=latest %s -emit-llvm -o - | FileCheck --check-prefix=V39 --check-prefix=V5 %s
+
+typedef __attribute__((vector_size(8))) long long v1xi64;
+void clang39(v1xi64) {}
+// PRE39: @_Z7clang39Dv1_x(i64
+// V39: @_Z7clang39Dv1_x(double
+
+struct A {
+ A(const A&) = default;
+ A(A&&);
+};
+void clang5(A) {}
+// PRE5: @_Z6clang51A()
+// V5: @_Z6clang51A(%{{.*}}*
diff --git a/src/llvm-project/clang/test/CodeGenCXX/clang-sections-tentative.c b/src/llvm-project/clang/test/CodeGenCXX/clang-sections-tentative.c
new file mode 100644
index 0000000..e663079
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/clang-sections-tentative.c
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -x c -emit-llvm -triple arm-none-eabi -o - %s | FileCheck %s
+
+// Test that section attributes are attached to C tentative definitions as per
+// '#pragma clang section' directives.
+
+#pragma clang section bss = ".bss.1"
+int x; // bss.1
+
+#pragma clang section bss = ""
+int x; // stays in .bss.1
+int y; // not assigned a section attribute
+int z; // not assigned a section attribute
+
+#pragma clang section bss = ".bss.2"
+int x; // stays in .bss.1
+int y; // .bss.2
+
+// Test the same for `const` declarations.
+#pragma clang section rodata = ".rodata.1"
+const int cx; // rodata.1
+
+#pragma clang section rodata = ""
+const int cx; // stays in .rodata.1
+const int cy; // not assigned a section attribute
+const int cz; // not assigned a rodata section attribute
+
+#pragma clang section rodata = ".rodata.2"
+const int cx; // stays in .rodata.1
+const int cy; // .rodata.2
+
+// CHECK: @x = global i32 0, align 4 #0
+// CHECK: @y = global i32 0, align 4 #1
+// CHECK: @z = common global i32 0, align 4
+// CHECK: @cx = constant i32 0, align 4 #2
+// CHECK: @cy = constant i32 0, align 4 #3
+// CHECK: @cz = constant i32 0, align 4 #1
+
+// CHECK: attributes #0 = { "bss-section"=".bss.1" }
+// CHECK: attributes #1 = { "bss-section"=".bss.2" }
+// CHECK: attributes #2 = { "bss-section"=".bss.2" "rodata-section"=".rodata.1" }
+// CHECK: attributes #3 = { "bss-section"=".bss.2" "rodata-section"=".rodata.2" }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/clang-sections.cpp b/src/llvm-project/clang/test/CodeGenCXX/clang-sections.cpp
new file mode 100644
index 0000000..4fe42ea
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/clang-sections.cpp
@@ -0,0 +1,78 @@
+// RUN: %clang_cc1 -emit-llvm -triple arm-none-eabi -o - %s | FileCheck %s
+// Test that global variables, statics and functions are attached section-attributes
+// as per '#pragma clang section' directives.
+
+extern "C" {
+// test with names for each section
+#pragma clang section bss="my_bss.1" data="my_data.1" rodata="my_rodata.1"
+#pragma clang section text="my_text.1"
+int a; // my_bss.1
+int b = 1; // my_data.1
+int c[4]; // my_bss.1
+short d[5] = {0}; // my_bss.1
+short e[6] = {0, 0, 1}; // my_data.1
+extern const int f;
+const int f = 2; // my_rodata.1
+int foo(void) { // my_text.1
+ return b;
+}
+static int g[2]; // my_bss.1
+#pragma clang section bss=""
+int h; // default - .bss
+#pragma clang section data="" bss="my_bss.2" text="my_text.2"
+int i = 0; // my_bss.2
+extern const int j;
+const int j = 4; // default - .rodata
+int k; // my_bss.2
+extern int zoo(int *x, int *y);
+int goo(void) { // my_text.2
+ static int lstat_h; // my_bss.2
+ return zoo(g, &lstat_h);
+}
+#pragma clang section rodata="my_rodata.2" data="my_data.2"
+int l = 5; // my_data.2
+extern const int m;
+const int m = 6; // my_rodata.2
+#pragma clang section rodata="" data="" bss="" text=""
+int n; // default
+int o = 6; // default
+extern const int p;
+const int p = 7; // default
+int hoo(void) {
+ return b;
+}
+}
+//CHECK: @a = global i32 0, align 4 #0
+//CHECK: @b = global i32 1, align 4 #0
+//CHECK: @c = global [4 x i32] zeroinitializer, align 4 #0
+//CHECK: @d = global [5 x i16] zeroinitializer, align 2 #0
+//CHECK: @e = global [6 x i16] [i16 0, i16 0, i16 1, i16 0, i16 0, i16 0], align 2 #0
+//CHECK: @f = constant i32 2, align 4 #0
+
+//CHECK: @h = global i32 0, align 4 #1
+//CHECK: @i = global i32 0, align 4 #2
+//CHECK: @j = constant i32 4, align 4 #2
+//CHECK: @k = global i32 0, align 4 #2
+//CHECK: @_ZZ3gooE7lstat_h = internal global i32 0, align 4 #2
+//CHECK: @_ZL1g = internal global [2 x i32] zeroinitializer, align 4 #0
+
+//CHECK: @l = global i32 5, align 4 #3
+//CHECK: @m = constant i32 6, align 4 #3
+
+//CHECK: @n = global i32 0, align 4
+//CHECK: @o = global i32 6, align 4
+//CHECK: @p = constant i32 7, align 4
+
+//CHECK: define i32 @foo() #4 {
+//CHECK: define i32 @goo() #5 {
+//CHECK: declare i32 @zoo(i32*, i32*) #6
+//CHECK: define i32 @hoo() #7 {
+
+//CHECK: attributes #0 = { "bss-section"="my_bss.1" "data-section"="my_data.1" "rodata-section"="my_rodata.1" }
+//CHECK: attributes #1 = { "data-section"="my_data.1" "rodata-section"="my_rodata.1" }
+//CHECK: attributes #2 = { "bss-section"="my_bss.2" "rodata-section"="my_rodata.1" }
+//CHECK: attributes #3 = { "bss-section"="my_bss.2" "data-section"="my_data.2" "rodata-section"="my_rodata.2" }
+//CHECK: attributes #4 = { {{.*"implicit-section-name"="my_text.1".*}} }
+//CHECK: attributes #5 = { {{.*"implicit-section-name"="my_text.2".*}} }
+//CHECK-NOT: attributes #6 = { {{.*"implicit-section-name".*}} }
+//CHECK-NOT: attributes #7 = { {{.*"implicit-section-name".*}} }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/class-layout.cpp b/src/llvm-project/clang/test/CodeGenCXX/class-layout.cpp
new file mode 100644
index 0000000..610dbc5
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/class-layout.cpp
@@ -0,0 +1,102 @@
+// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+// An extra byte should be allocated for an empty class.
+namespace Test1 {
+ // CHECK: %"struct.Test1::A" = type { i8 }
+ struct A { } *a;
+}
+
+namespace Test2 {
+ // No need to add tail padding here.
+ // CHECK: %"struct.Test2::A" = type { i8*, i32 }
+ struct A { void *a; int b; } *a;
+}
+
+namespace Test3 {
+ // C should have a vtable pointer.
+ // CHECK: %"struct.Test3::A" = type <{ i32 (...)**, i32, [4 x i8] }>
+ struct A { virtual void f(); int a; } *a;
+}
+
+namespace Test4 {
+ // Test from PR5589.
+ // CHECK: %"struct.Test4::B" = type { %"struct.Test4::A", i16, double }
+ // CHECK: %"struct.Test4::A" = type { i32, i8, float }
+ struct A {
+ int a;
+ char c;
+ float b;
+ };
+ struct B : public A {
+ short d;
+ double e;
+ } *b;
+}
+
+namespace Test5 {
+ struct A {
+ virtual void f();
+ char a;
+ };
+
+ // CHECK: %"struct.Test5::B" = type { %"struct.Test5::A.base", i8, i8, [5 x i8] }
+ struct B : A {
+ char b : 1;
+ char c;
+ } *b;
+}
+
+// PR10912: don't crash
+namespace Test6 {
+ template <typename T> class A {
+ // If T is complete, IR-gen will want to translate it recursively
+ // when translating T*.
+ T *foo;
+ };
+
+ class B;
+
+ // This causes IR-gen to have an incomplete translation of A<B>
+ // sitting around.
+ A<B> *a;
+
+ class C {};
+ class B : public C {
+ // This forces Sema to instantiate A<B>, which triggers a callback
+ // to IR-gen. Because of the previous, incomplete translation,
+ // IR-gen actually cares, and it immediately tries to complete
+ // A<B>'s IR type. That, in turn, causes the translation of B*.
+ // B isn't complete yet, but it has a definition, and if we try to
+ // compute a record layout for that definition then we'll really
+ // regret it later.
+ A<B> a;
+ };
+
+ // The derived class E and empty base class C are required to
+ // provoke the original assertion.
+ class E : public B {};
+ E *e;
+}
+
+// <rdar://problem/11324125>: Make sure this doesn't crash. (It's okay
+// if we start rejecting it at some point.)
+namespace Test7 {
+ #pragma pack (1)
+ class A {};
+ // CHECK: %"class.Test7::B" = type <{ i32 (...)**, %"class.Test7::A" }>
+ class B {
+ virtual ~B();
+ A a;
+ };
+ B* b;
+ #pragma pack ()
+}
+
+// Shouldn't crash.
+namespace Test8 {
+ struct A {};
+ struct D { int a; };
+ struct B : virtual D, A { };
+ struct C : B, A { void f() {} };
+ C c;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/code-seg.cpp b/src/llvm-project/clang/test/CodeGenCXX/code-seg.cpp
new file mode 100644
index 0000000..7dad927
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/code-seg.cpp
@@ -0,0 +1,139 @@
+// RUN: %clang_cc1 -emit-llvm -triple i686-pc-win32 -fms-extensions -verify -o - %s | FileCheck %s
+// expected-no-diagnostics
+
+// Simple case
+
+int __declspec(code_seg("foo_one")) bar_one() { return 1; }
+//CHECK: define {{.*}}bar_one{{.*}} section "foo_one"
+
+// Simple case - explicit attribute used over pragma
+#pragma code_seg("foo_two")
+int __declspec(code_seg("foo_three")) bar2() { return 2; }
+//CHECK: define {{.*}}bar2{{.*}} section "foo_three"
+
+// Check that attribute on one function doesn't affect another
+int another1() { return 1001; }
+//CHECK: define {{.*}}another1{{.*}} section "foo_two"
+
+// Member functions
+
+struct __declspec(code_seg("foo_four")) Foo {
+ int bar3() {return 0;}
+ int bar4();
+ int __declspec(code_seg("foo_six")) bar6() { return 6; }
+ int bar7() { return 7; }
+ struct Inner {
+ int bar5() { return 5; }
+ } z;
+ virtual int baz1() { return 1; }
+};
+
+struct __declspec(code_seg("foo_four")) FooTwo : Foo {
+ int baz1() { return 20; }
+};
+
+int caller1() {
+ Foo f; return f.bar3();
+}
+
+//CHECK: define {{.*}}bar3@Foo{{.*}} section "foo_four"
+int Foo::bar4() { return 4; }
+//CHECK: define {{.*}}bar4@Foo{{.*}} section "foo_four"
+
+#pragma code_seg("someother")
+
+int caller2() {
+ Foo f;
+ Foo *fp = new FooTwo;
+ return f.z.bar5() + f.bar6() + f.bar7() + fp->baz1();
+}
+// MS Compiler and Docs do not match for nested routines
+// Doc says: define {{.*}}bar5@Inner@Foo{{.*}} section "foo_four"
+// Compiler says: define {{.*}}bar5@Inner@Foo{{.*}} section "foo_two"
+// A bug has been reported: see https://reviews.llvm.org/D22931, the
+// Microsoft feedback page is no longer available.
+//CHECK: define {{.*}}bar5@Inner@Foo{{.*}} section "foo_two"
+//CHECK: define {{.*}}bar6@Foo{{.*}} section "foo_six"
+//CHECK: define {{.*}}bar7@Foo{{.*}} section "foo_four"
+// Check that code_seg active at class declaration is not used on member
+// declared outside class when it is not active.
+
+#pragma code_seg(push,"AnotherSeg")
+
+struct FooThree {
+ int bar8();
+ int bar9() { return 9; }
+};
+
+#pragma code_seg(pop)
+
+
+int FooThree::bar8() {return 0;}
+
+int caller3()
+{
+ FooThree f;
+ return f.bar8() + f.bar9();
+}
+
+//CHECK: define {{.*}}bar8@FooThree{{.*}} section "someother"
+//CHECK: define {{.*}}bar9@FooThree{{.*}} section "AnotherSeg"
+
+struct NonTrivialCopy {
+ NonTrivialCopy();
+ NonTrivialCopy(const NonTrivialCopy&);
+ ~NonTrivialCopy();
+};
+
+// check the section for compiler-generated function with declspec.
+
+struct __declspec(code_seg("foo_seven")) FooFour {
+ FooFour() {}
+ int __declspec(code_seg("foo_eight")) bar10(int t) { return t; }
+ NonTrivialCopy f;
+};
+
+//CHECK: define {{.*}}0FooFour@@QAE@ABU0@@Z{{.*}} section "foo_seven"
+// check the section for compiler-generated function with no declspec.
+
+struct FooFive {
+ FooFive() {}
+ int __declspec(code_seg("foo_nine")) bar11(int t) { return t; }
+ NonTrivialCopy f;
+};
+
+//CHECK: define {{.*}}0FooFive@@QAE@ABU0@@Z{{.*}} section "someother"
+
+#pragma code_seg("YetAnother")
+int caller4()
+{
+ FooFour z1;
+ FooFour z2 = z1;
+ FooFive y1;
+ FooFive y2 = y1;
+ return z2.bar10(0) + y2.bar11(1);
+}
+
+//CHECK: define {{.*}}bar10@FooFour{{.*}} section "foo_eight"
+//CHECK: define {{.*}}bar11@FooFive{{.*}} section "foo_nine"
+
+struct FooSix {
+ #pragma code_seg("foo_ten")
+ int bar12() { return 12; }
+ #pragma code_seg("foo_eleven")
+ int bar13() { return 13; }
+};
+
+int bar14() { return 14; }
+//CHECK: define {{.*}}bar14{{.*}} section "foo_eleven"
+
+int caller5()
+{
+ FooSix fsix;
+ return fsix.bar12() + fsix.bar13();
+}
+
+//CHECK: define {{.*}}bar12@FooSix{{.*}} section "foo_ten"
+//CHECK: define {{.*}}bar13@FooSix{{.*}} section "foo_eleven"
+//CHECK: define {{.*}}baz1@FooTwo{{.*}} section "foo_four"
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/code-seg1.cpp b/src/llvm-project/clang/test/CodeGenCXX/code-seg1.cpp
new file mode 100644
index 0000000..93be3e5
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/code-seg1.cpp
@@ -0,0 +1,87 @@
+// RUN: %clang_cc1 -emit-llvm -triple i686-pc-win32 -fms-extensions -verify -o - %s | FileCheck %s
+// expected-no-diagnostics
+// The Microsoft document says: "When this attribute is applied to a class,
+// all member functions of the class and nested classes - this includes
+// compiler-generated special member functions - are put in the specified segment."
+// But the MS compiler does not always follow that. A bug has been reported:
+// see https://reviews.llvm.org/D22931, the Microsoft feedback page is no
+// longer available.
+// The MS compiler will apply a declspec from the parent class if there is no
+// #pragma code_seg active at the class definition. If there is an active
+// code_seg that is used instead.
+
+// No active code_seg
+
+struct __declspec(code_seg("foo_outer")) Foo1 {
+ struct Inner {
+ void bar1();
+ static void bar2();
+ };
+};
+void Foo1::Inner::bar1() {}
+void Foo1::Inner::bar2() {}
+
+//CHECK: define {{.*}}bar1@Inner@Foo1{{.*}} section "foo_outer"
+//CHECK: define {{.*}}bar2@Inner@Foo1{{.*}} section "foo_outer"
+
+struct __declspec(code_seg("foo_outer")) Foo2 {
+ struct __declspec(code_seg("foo_inner")) Inner {
+ void bar1();
+ static void bar2();
+ };
+};
+void Foo2::Inner::bar1() {}
+void Foo2::Inner::bar2() {}
+
+//CHECK: define {{.*}}bar1@Inner@Foo2{{.*}} section "foo_inner"
+//CHECK: define {{.*}}bar2@Inner@Foo2{{.*}} section "foo_inner"
+
+#pragma code_seg(push, "otherseg")
+struct __declspec(code_seg("foo_outer")) Foo3 {
+ struct Inner {
+ void bar1();
+ static void bar2();
+ };
+};
+void Foo3::Inner::bar1() {}
+void Foo3::Inner::bar2() {}
+
+//CHECK: define {{.*}}bar1@Inner@Foo3{{.*}} section "otherseg"
+//CHECK: define {{.*}}bar2@Inner@Foo3{{.*}} section "otherseg"
+
+struct __declspec(code_seg("foo_outer")) Foo4 {
+ struct __declspec(code_seg("foo_inner")) Inner {
+ void bar1();
+ static void bar2();
+ };
+};
+void Foo4::Inner::bar1() {}
+void Foo4::Inner::bar2() {}
+
+//CHECK: define {{.*}}bar1@Inner@Foo4{{.*}} section "foo_inner"
+//CHECK: define {{.*}}bar2@Inner@Foo4{{.*}} section "foo_inner"
+
+#pragma code_seg(pop)
+// Back to no active pragma
+struct __declspec(code_seg("foo_outer")) Foo5 {
+ struct Inner {
+ void bar1();
+ static void bar2();
+ struct __declspec(code_seg("inner1_seg")) Inner1 {
+ struct Inner2 {
+ void bar1();
+ static void bar2();
+ };
+ };
+ };
+};
+void Foo5::Inner::bar1() {}
+void Foo5::Inner::bar2() {}
+void Foo5::Inner::Inner1::Inner2::bar1() {}
+void Foo5::Inner::Inner1::Inner2::bar2() {}
+
+//CHECK: define {{.*}}bar1@Inner@Foo5{{.*}} section "foo_outer"
+//CHECK: define {{.*}}bar2@Inner@Foo5{{.*}} section "foo_outer"
+//CHECK: define {{.*}}bar1@Inner2@Inner1@Inner@Foo5{{.*}} section "inner1_seg"
+//CHECK: define {{.*}}bar2@Inner2@Inner1@Inner@Foo5{{.*}} section "inner1_seg"
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/code-seg2.cpp b/src/llvm-project/clang/test/CodeGenCXX/code-seg2.cpp
new file mode 100644
index 0000000..ab72bf4
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/code-seg2.cpp
@@ -0,0 +1,111 @@
+// RUN: %clang_cc1 -emit-llvm -triple i686-pc-win32 -std=c++11 -fms-extensions -verify -o - %s | FileCheck %s
+// expected-no-diagnostics
+
+// Class member templates
+
+#pragma code_seg(push, "something")
+
+template <typename T>
+struct __declspec(code_seg("foo_one")) ClassOne {
+ int bar1(T t) { return int(t); }
+ int bar2(T t);
+ int bar3(T t);
+};
+
+template <typename T>
+int ClassOne<T>::bar2(T t) {
+ return int(t);
+}
+
+int caller1() {
+ ClassOne<int> coi;
+ return coi.bar1(6) + coi.bar2(3);
+}
+
+//CHECK: define {{.*}}bar1@?$ClassOne{{.*}} section "foo_one"
+//CHECK: define {{.*}}bar2@?$ClassOne{{.*}} section "foo_one"
+
+
+template <typename T>
+struct ClassTwo {
+ int bar11(T t) { return int(t); }
+ int bar22(T t);
+ int bar33(T t);
+};
+
+#pragma code_seg("newone")
+
+template <typename T>
+int ClassTwo<T>::bar22(T t) {
+ return int(t);
+}
+
+#pragma code_seg("someother")
+
+template <typename T>
+int ClassTwo<T>::bar33(T t) {
+ return int(t);
+}
+
+#pragma code_seg("yetanother")
+
+int caller2() {
+ ClassTwo<int> coi;
+ return coi.bar11(6) + coi.bar22(3) + coi.bar33(44);
+}
+
+//CHECK: define {{.*}}bar11@?$ClassTwo{{.*}} section "something"
+//CHECK: define {{.*}}bar22@?$ClassTwo{{.*}} section "newone"
+//CHECK: define {{.*}}bar33@?$ClassTwo{{.*}} section "someother"
+
+template<>
+struct ClassOne<double>
+{
+ int bar44(double d) { return 1; }
+};
+template<>
+struct __declspec(code_seg("foo_three")) ClassOne<long>
+{
+ int bar55(long d) { return 1; }
+};
+
+#pragma code_seg("onemore")
+int caller3() {
+ ClassOne<double> d;
+ ClassOne<long> l;
+ return d.bar44(1.0)+l.bar55(1);
+}
+
+//CHECK: define {{.*}}bar44{{.*}} section "yetanother"
+//CHECK: define {{.*}}bar55{{.*}} section "foo_three"
+
+
+// Function templates
+template <typename T>
+int __declspec(code_seg("foo_four")) bar66(T t) { return int(t); }
+
+// specializations do not take the segment from primary
+template<>
+int bar66(int i) { return 0; }
+
+#pragma code_seg(pop)
+
+template<>
+int bar66(char c) { return 0; }
+
+struct A1 {int i;};
+template<>
+int __declspec(code_seg("foo_five")) bar66(A1 a) { return a.i; }
+
+int caller4()
+{
+// but instantiations do use the section from the primary
+return bar66(0) + bar66(1.0) + bar66('c');
+}
+//CHECK: define {{.*}}bar66@H{{.*}} section "onemore"
+//CHECK-NOT: define {{.*}}bar66@D{{.*}} section
+//CHECK: define {{.*}}bar66@UA1{{.*}} section "foo_five"
+//CHECK: define {{.*}}bar66@N{{.*}} section "foo_four"
+
+
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/code-seg3.cpp b/src/llvm-project/clang/test/CodeGenCXX/code-seg3.cpp
new file mode 100644
index 0000000..d6f2677
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/code-seg3.cpp
@@ -0,0 +1,65 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -fms-extensions %s -triple x86_64-pc-win32
+// expected-no-diagnostics
+
+// Non-Member Function Overloading is involved
+
+int __declspec(code_seg("foo_one")) bar_one(int) { return 1; }
+//CHECK: define {{.*}}bar_one{{.*}} section "foo_one"
+int __declspec(code_seg("foo_two")) bar_one(int,float) { return 11; }
+//CHECK: define {{.*}}bar_one{{.*}} section "foo_two"
+int __declspec(code_seg("foo_three")) bar_one(float) { return 12; }
+//CHECK: define {{.*}}bar_one{{.*}} section "foo_three"
+
+// virtual function overloading is involved
+
+struct __declspec(code_seg("my_one")) Base3 {
+ virtual int barA(int) { return 1; }
+ virtual int barA(int,float) { return 2; }
+ virtual int barA(float) { return 3; }
+
+ virtual void __declspec(code_seg("my_two")) barB(int) { }
+ virtual void __declspec(code_seg("my_three")) barB(float) { }
+ virtual void __declspec(code_seg("my_four")) barB(int, float) { }
+
+};
+
+//CHECK: define {{.*}}barA@Base3{{.*}} section "my_one"
+//CHECK: define {{.*}}barA@Base3{{.*}} section "my_one"
+//CHECK: define {{.*}}barA@Base3{{.*}} section "my_one"
+//CHECK: define {{.*}}barB@Base3{{.*}} section "my_two"
+//CHECK: define {{.*}}barB@Base3{{.*}} section "my_three"
+//CHECK: define {{.*}}barB@Base3{{.*}} section "my_four"
+
+#pragma code_seg("another")
+// Member functions
+struct __declspec(code_seg("foo_four")) Foo {
+ int bar3() {return 0;}
+ __declspec(code_seg("foo_lala")) int bar4() {return 0;} }; int caller() {Foo f; return f.bar3() + f.bar4(); }
+
+//CHECK: define {{.*}}bar3@Foo{{.*}} section "foo_four"
+//CHECK: define {{.*}}bar4@Foo{{.*}} section "foo_lala"
+
+// Lambdas
+#pragma code_seg("something")
+
+int __declspec(code_seg("foo")) bar1()
+{
+ int lala = 4;
+ auto l = [=](int i) { return i+4; };
+ return l(-4);
+}
+
+//CHECK: define {{.*}}bar1{{.*}} section "foo"
+//CHECK: define {{.*}}lambda{{.*}}bar1{{.*}} section "something"
+
+double __declspec(code_seg("foo")) bar2()
+{
+ double lala = 4.0;
+ auto l = [=](double d) __declspec(code_seg("another")) { return d+4.0; };
+ return l(4.0);
+}
+
+//CHECK: define {{.*}}bar2{{.*}} section "foo"
+//CHECK: define {{.*}}lambda{{.*}}bar2{{.*}} section "another"
+
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/compound-literals.cpp b/src/llvm-project/clang/test/CodeGenCXX/compound-literals.cpp
new file mode 100644
index 0000000..a9882bc
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/compound-literals.cpp
@@ -0,0 +1,85 @@
+// RUN: %clang_cc1 -std=c++11 -triple armv7-none-eabi -emit-llvm -o - %s | FileCheck %s
+
+struct X {
+ X();
+ X(const X&);
+ X(const char*);
+ ~X();
+};
+
+struct Y {
+ int i;
+ X x;
+};
+
+// CHECK: @.compoundliteral = internal global [5 x i32] [i32 1, i32 2, i32 3, i32 4, i32 5], align 4
+// CHECK: @q = global i32* getelementptr inbounds ([5 x i32], [5 x i32]* @.compoundliteral, i32 0, i32 0), align 4
+
+// CHECK-LABEL: define i32 @_Z1fv()
+int f() {
+ // CHECK: [[LVALUE:%[a-z0-9.]+]] = alloca
+ // CHECK-NEXT: [[I:%[a-z0-9]+]] = getelementptr inbounds {{.*}}, {{.*}}* [[LVALUE]], i32 0, i32 0
+ // CHECK-NEXT: store i32 17, i32* [[I]]
+ // CHECK-NEXT: [[X:%[a-z0-9]+]] = getelementptr inbounds {{.*}} [[LVALUE]], i32 0, i32 1
+ // CHECK-NEXT: call %struct.X* @_ZN1XC1EPKc({{.*}}[[X]]
+ // CHECK-NEXT: [[I:%[a-z0-9]+]] = getelementptr inbounds {{.*}} [[LVALUE]], i32 0, i32 0
+ // CHECK-NEXT: [[RESULT:%[a-z0-9]+]] = load i32, i32*
+ // CHECK-NEXT: call %struct.Y* @_ZN1YD1Ev
+ // CHECK-NEXT: ret i32 [[RESULT]]
+ return ((Y){17, "seventeen"}).i;
+}
+
+// CHECK-LABEL: define i32 @_Z1gv()
+int g() {
+ // CHECK: store [2 x i32]* %{{[a-z0-9.]+}}, [2 x i32]** [[V:%[a-z0-9.]+]]
+ const int (&v)[2] = (int [2]) {1,2};
+
+ // CHECK: [[A:%[a-z0-9.]+]] = load [2 x i32]*, [2 x i32]** [[V]]
+ // CHECK-NEXT: [[A0ADDR:%[a-z0-9.]+]] = getelementptr inbounds [2 x i32], [2 x i32]* [[A]], i32 0, {{.*}} 0
+ // CHECK-NEXT: [[A0:%[a-z0-9.]+]] = load i32, i32* [[A0ADDR]]
+ // CHECK-NEXT: ret i32 [[A0]]
+ return v[0];
+}
+
+// GCC's compound-literals-in-C++ extension lifetime-extends a compound literal
+// (or a C++11 list-initialized temporary!) if:
+// - it is at global scope
+// - it has array type
+// - it has a constant initializer
+
+struct Z { int i[3]; };
+int *p = (Z){ {1, 2, 3} }.i;
+// CHECK: define {{.*}}__cxx_global_var_init()
+// CHECK: alloca %struct.Z
+// CHECK: store i32* %{{.*}}, i32** @p
+
+int *q = (int [5]){1, 2, 3, 4, 5};
+// (constant initialization, checked above)
+
+extern int n;
+int *r = (int [5]){1, 2, 3, 4, 5} + n;
+// CHECK-LABEL: define {{.*}}__cxx_global_var_init.1()
+// CHECK: %[[PTR:.*]] = getelementptr inbounds i32, i32* getelementptr inbounds ([5 x i32], [5 x i32]* @.compoundliteral.2, i32 0, i32 0), i32 %
+// CHECK: store i32* %[[PTR]], i32** @r
+
+int *PR21912_1 = (int []){} + n;
+// CHECK-LABEL: define {{.*}}__cxx_global_var_init.3()
+// CHECK: %[[PTR:.*]] = getelementptr inbounds i32, i32* getelementptr inbounds ([0 x i32], [0 x i32]* @.compoundliteral.4, i32 0, i32 0), i32 %
+// CHECK: store i32* %[[PTR]], i32** @PR21912_1
+
+union PR21912Ty {
+ long long l;
+ double d;
+};
+union PR21912Ty *PR21912_2 = (union PR21912Ty[]){{.d = 2.0}, {.l = 3}} + n;
+// CHECK-LABEL: define {{.*}}__cxx_global_var_init.5()
+// CHECK: %[[PTR:.*]] = getelementptr inbounds %union.PR21912Ty, %union.PR21912Ty* getelementptr inbounds ([2 x %union.PR21912Ty], [2 x %union.PR21912Ty]* bitcast (<{ { double }, %union.PR21912Ty }>* @.compoundliteral.6 to [2 x %union.PR21912Ty]*), i32 0, i32 0), i32 %
+// CHECK: store %union.PR21912Ty* %[[PTR]], %union.PR21912Ty** @PR21912_2, align 4
+
+// This compound literal should have local scope.
+int computed_with_lambda = [] {
+ int *array = (int[]) { 1, 3, 5, 7 };
+ return array[0];
+}();
+// CHECK-LABEL: define internal i32 @{{.*}}clEv
+// CHECK: alloca [4 x i32]
diff --git a/src/llvm-project/clang/test/CodeGenCXX/condition.cpp b/src/llvm-project/clang/test/CodeGenCXX/condition.cpp
new file mode 100644
index 0000000..fbba077
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/condition.cpp
@@ -0,0 +1,317 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
+void *f();
+
+template <typename T> T* g() {
+ if (T* t = f())
+ return t;
+
+ return 0;
+}
+
+void h() {
+ void *a = g<void>();
+}
+
+struct X {
+ X();
+ X(const X&);
+ ~X();
+ operator bool();
+};
+
+struct Y {
+ Y();
+ ~Y();
+};
+
+X getX();
+
+// CHECK-LABEL: define void @_Z11if_destructi(
+void if_destruct(int z) {
+ // Verify that the condition variable is destroyed at the end of the
+ // "if" statement.
+ // CHECK: call void @_ZN1XC1Ev
+ // CHECK: call zeroext i1 @_ZN1XcvbEv
+ if (X x = X()) {
+ // CHECK: store i32 18
+ z = 18;
+ }
+ // CHECK: call void @_ZN1XD1Ev
+ // CHECK: store i32 17
+ z = 17;
+
+ // CHECK: call void @_ZN1XC1Ev
+ if (X x = X())
+ Y y;
+ // CHECK: br
+ // CHECK: call void @_ZN1YC1Ev
+ // CHECK: call void @_ZN1YD1Ev
+ // CHECK: br
+ // CHECK: call void @_ZN1XD1Ev
+
+ // CHECK: call void @_Z4getXv
+ // CHECK: call zeroext i1 @_ZN1XcvbEv
+ // CHECK: call void @_ZN1XD1Ev
+ // CHECK: br
+ if (getX()) { }
+
+ // CHECK: ret
+}
+
+struct ConvertibleToInt {
+ ConvertibleToInt();
+ ~ConvertibleToInt();
+ operator int();
+};
+
+ConvertibleToInt getConvToInt();
+
+void switch_destruct(int z) {
+ // CHECK: call void @_ZN16ConvertibleToIntC1Ev
+ switch (ConvertibleToInt conv = ConvertibleToInt()) {
+ case 0:
+ break;
+
+ default:
+ // CHECK: store i32 19
+ z = 19;
+ break;
+ }
+ // CHECK: call void @_ZN16ConvertibleToIntD1Ev
+ // CHECK: store i32 20
+ z = 20;
+
+ // CHECK: call void @_Z12getConvToIntv
+ // CHECK: call i32 @_ZN16ConvertibleToIntcviEv
+ // CHECK: call void @_ZN16ConvertibleToIntD1Ev
+ switch(getConvToInt()) {
+ case 0:
+ break;
+ }
+ // CHECK: store i32 27
+ z = 27;
+ // CHECK: ret
+}
+
+int foo();
+
+// CHECK-LABEL: define void @_Z14while_destructi
+void while_destruct(int z) {
+ // CHECK: [[Z:%.*]] = alloca i32
+ // CHECK: [[CLEANUPDEST:%.*]] = alloca i32
+ while (X x = X()) {
+ // CHECK: call void @_ZN1XC1Ev
+ // CHECK-NEXT: [[COND:%.*]] = call zeroext i1 @_ZN1XcvbEv
+ // CHECK-NEXT: br i1 [[COND]]
+
+ // Loop-exit staging block.
+ // CHECK: store i32 3, i32* [[CLEANUPDEST]]
+ // CHECK-NEXT: br
+
+ // While body.
+ // CHECK: store i32 21, i32* [[Z]]
+ // CHECK: store i32 0, i32* [[CLEANUPDEST]]
+ // CHECK-NEXT: br
+ z = 21;
+
+ // Cleanup.
+ // CHECK: call void @_ZN1XD1Ev
+ // CHECK-NEXT: [[DEST:%.*]] = load i32, i32* [[CLEANUPDEST]]
+ // CHECK-NEXT: switch i32 [[DEST]]
+ }
+
+ // CHECK: store i32 22, i32* [[Z]]
+ z = 22;
+
+ // CHECK: call void @_Z4getXv
+ // CHECK-NEXT: call zeroext i1 @_ZN1XcvbEv
+ // CHECK-NEXT: call void @_ZN1XD1Ev
+ // CHECK-NEXT: br
+ while(getX()) { }
+
+ // CHECK: store i32 25, i32* [[Z]]
+ z = 25;
+
+ // CHECK: ret
+}
+
+// CHECK-LABEL: define void @_Z12for_destructi(
+void for_destruct(int z) {
+ // CHECK: [[Z:%.*]] = alloca i32
+ // CHECK: [[CLEANUPDEST:%.*]] = alloca i32
+ // CHECK: [[I:%.*]] = alloca i32
+ // CHECK: call void @_ZN1YC1Ev
+ // CHECK-NEXT: br
+ // -> %for.cond
+
+ for(Y y = Y(); X x = X(); ++z) {
+ // %for.cond: The loop condition.
+ // CHECK: call void @_ZN1XC1Ev
+ // CHECK-NEXT: [[COND:%.*]] = call zeroext i1 @_ZN1XcvbEv(
+ // CHECK-NEXT: br i1 [[COND]]
+ // -> %for.body, %for.cond.cleanup
+
+ // %for.cond.cleanup: Exit cleanup staging.
+ // CHECK: store i32 2, i32* [[CLEANUPDEST]]
+ // CHECK-NEXT: br
+ // -> %cleanup
+
+ // %for.body:
+ // CHECK: store i32 23, i32* [[Z]]
+ // CHECK-NEXT: br
+ // -> %for.inc
+ z = 23;
+
+ // %for.inc:
+ // CHECK: [[TMP:%.*]] = load i32, i32* [[Z]]
+ // CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP]], 1
+ // CHECK-NEXT: store i32 [[INC]], i32* [[Z]]
+ // CHECK-NEXT: store i32 0, i32* [[CLEANUPDEST]]
+ // CHECK-NEXT: br
+ // -> %cleanup
+
+ // %cleanup: Destroys X.
+ // CHECK: call void @_ZN1XD1Ev
+ // CHECK-NEXT: [[YDESTTMP:%.*]] = load i32, i32* [[CLEANUPDEST]]
+ // CHECK-NEXT: switch i32 [[YDESTTMP]]
+ // 0 -> %cleanup.cont, default -> %cleanup1
+
+ // %cleanup.cont: (eliminable)
+ // CHECK: br
+ // -> %for.cond
+
+ // %cleanup1: Destroys Y.
+ // CHECK: call void @_ZN1YD1Ev(
+ // CHECK-NEXT: br
+ // -> %for.end
+ }
+
+ // %for.end:
+ // CHECK: store i32 24
+ z = 24;
+
+ // CHECK-NEXT: store i32 0, i32* [[I]]
+ // CHECK-NEXT: br
+ // -> %for.cond6
+
+ // %for.cond6:
+ // CHECK: call void @_Z4getXv
+ // CHECK-NEXT: call zeroext i1 @_ZN1XcvbEv
+ // CHECK-NEXT: call void @_ZN1XD1Ev
+ // CHECK-NEXT: br
+ // -> %for.body10, %for.end16
+
+ // %for.body10:
+ // CHECK: br
+ // -> %for.inc11
+
+ // %for.inc11:
+ // CHECK: call void @_Z4getXv
+ // CHECK-NEXT: load i32, i32* [[I]]
+ // CHECK-NEXT: add
+ // CHECK-NEXT: store
+ // CHECK-NEXT: call void @_ZN1XD1Ev
+ // CHECK-NEXT: br
+ // -> %for.cond6
+ int i = 0;
+ for(; getX(); getX(), ++i) { }
+
+ // %for.end16
+ // CHECK: store i32 26
+ z = 26;
+
+ // CHECK-NEXT: ret void
+}
+
+void do_destruct(int z) {
+ // CHECK-LABEL: define void @_Z11do_destruct
+ do {
+ // CHECK: store i32 77
+ z = 77;
+ // CHECK: call void @_Z4getXv
+ // CHECK: call zeroext i1 @_ZN1XcvbEv
+ // CHECK: call void @_ZN1XD1Ev
+ // CHECK: br
+ } while (getX());
+ // CHECK: store i32 99
+ z = 99;
+ // CHECK: ret
+}
+
+int f(X);
+
+template<typename T>
+int instantiated(T x) {
+ int result;
+
+ // CHECK: call void @_ZN1XC1ERKS_
+ // CHECK: call i32 @_Z1f1X
+ // CHECK: call void @_ZN1XD1Ev
+ // CHECK: br
+ // CHECK: store i32 2
+ // CHECK: br
+ // CHECK: store i32 3
+ if (f(x)) { result = 2; } else { result = 3; }
+
+ // CHECK: call void @_ZN1XC1ERKS_
+ // CHECK: call i32 @_Z1f1X
+ // CHECK: call void @_ZN1XD1Ev
+ // CHECK: br
+ // CHECK: store i32 4
+ // CHECK: br
+ while (f(x)) { result = 4; }
+
+ // CHECK: call void @_ZN1XC1ERKS_
+ // CHECK: call i32 @_Z1f1X
+ // CHECK: call void @_ZN1XD1Ev
+ // CHECK: br
+ // CHECK: store i32 6
+ // CHECK: br
+ // CHECK: call void @_ZN1XC1ERKS_
+ // CHECK: call i32 @_Z1f1X
+ // CHECK: store i32 5
+ // CHECK: call void @_ZN1XD1Ev
+ // CHECK: br
+ for (; f(x); f(x), result = 5) {
+ result = 6;
+ }
+
+ // CHECK: call void @_ZN1XC1ERKS_
+ // CHECK: call i32 @_Z1f1X
+ // CHECK: call void @_ZN1XD1Ev
+ // CHECK: switch i32
+ // CHECK: store i32 7
+ // CHECK: store i32 8
+ switch (f(x)) {
+ case 0:
+ result = 7;
+ break;
+
+ case 1:
+ result = 8;
+ }
+
+ // CHECK: store i32 9
+ // CHECK: br
+ // CHECK: call void @_ZN1XC1ERKS_
+ // CHECK: call i32 @_Z1f1X
+ // CHECK: call void @_ZN1XD1Ev
+ // CHECK: br
+ do {
+ result = 9;
+ } while (f(x));
+
+ // CHECK: store i32 10
+ // CHECK: call void @_ZN1XC1ERKS_
+ // CHECK: call zeroext i1 @_ZN1XcvbEv
+ // CHECK: call void @_ZN1XD1Ev
+ // CHECK: br
+ do {
+ result = 10;
+ } while (X(x));
+
+ // CHECK: ret i32
+ return result;
+}
+
+template int instantiated(X);
diff --git a/src/llvm-project/clang/test/CodeGenCXX/conditional-expr-lvalue.cpp b/src/llvm-project/clang/test/CodeGenCXX/conditional-expr-lvalue.cpp
new file mode 100644
index 0000000..96aa8b0
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/conditional-expr-lvalue.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -emit-llvm-only %s
+void f(bool flag) {
+ int a = 1;
+ int b = 2;
+
+ (flag ? a : b) = 3;
+}
+
+// PR10756
+namespace test0 {
+ struct A {
+ A(const A &);
+ A &operator=(const A &);
+ A sub() const;
+ void foo() const;
+ };
+ void foo(bool cond, const A &a) {
+ (cond ? a : a.sub()).foo();
+ }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/conditional-gnu-ext.cpp b/src/llvm-project/clang/test/CodeGenCXX/conditional-gnu-ext.cpp
new file mode 100644
index 0000000..b073e0c
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/conditional-gnu-ext.cpp
@@ -0,0 +1,150 @@
+// 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;
+}
+}
+
+namespace test3 {
+ struct A {
+ A();
+ A(const A&);
+ ~A();
+ };
+
+ struct B {
+ B();
+ B(const B&);
+ ~B();
+ operator bool();
+ operator A();
+ };
+
+ B test0(B &x) {
+ // CHECK-LABEL: define void @_ZN5test35test0ERNS_1BE(
+ // CHECK: [[X:%.*]] = alloca [[B:%.*]]*,
+ // CHECK-NEXT: store [[B]]* {{%.*}}, [[B]]** [[X]]
+ // CHECK-NEXT: [[T0:%.*]] = load [[B]]*, [[B]]** [[X]]
+ // CHECK-NEXT: [[BOOL:%.*]] = call zeroext i1 @_ZN5test31BcvbEv([[B]]* [[T0]])
+ // CHECK-NEXT: br i1 [[BOOL]]
+ // CHECK: call void @_ZN5test31BC1ERKS0_([[B]]* [[RESULT:%.*]], [[B]]* dereferenceable({{[0-9]+}}) [[T0]])
+ // CHECK-NEXT: br label
+ // CHECK: call void @_ZN5test31BC1Ev([[B]]* [[RESULT]])
+ // CHECK-NEXT: br label
+ // CHECK: ret void
+ return x ?: B();
+ }
+
+ B test1() {
+ // CHECK-LABEL: define void @_ZN5test35test1Ev(
+ // CHECK: [[TEMP:%.*]] = alloca [[B]],
+ // CHECK-NEXT: call void @_ZN5test312test1_helperEv([[B]]* sret [[TEMP]])
+ // CHECK-NEXT: [[BOOL:%.*]] = call zeroext i1 @_ZN5test31BcvbEv([[B]]* [[TEMP]])
+ // CHECK-NEXT: br i1 [[BOOL]]
+ // CHECK: call void @_ZN5test31BC1ERKS0_([[B]]* [[RESULT:%.*]], [[B]]* dereferenceable({{[0-9]+}}) [[TEMP]])
+ // CHECK-NEXT: br label
+ // CHECK: call void @_ZN5test31BC1Ev([[B]]* [[RESULT]])
+ // CHECK-NEXT: br label
+ // CHECK: call void @_ZN5test31BD1Ev([[B]]* [[TEMP]])
+ // CHECK-NEXT: ret void
+ extern B test1_helper();
+ return test1_helper() ?: B();
+ }
+
+
+ A test2(B &x) {
+ // CHECK-LABEL: define void @_ZN5test35test2ERNS_1BE(
+ // CHECK: [[X:%.*]] = alloca [[B]]*,
+ // CHECK-NEXT: store [[B]]* {{%.*}}, [[B]]** [[X]]
+ // CHECK-NEXT: [[T0:%.*]] = load [[B]]*, [[B]]** [[X]]
+ // CHECK-NEXT: [[BOOL:%.*]] = call zeroext i1 @_ZN5test31BcvbEv([[B]]* [[T0]])
+ // CHECK-NEXT: br i1 [[BOOL]]
+ // CHECK: call void @_ZN5test31BcvNS_1AEEv([[A:%.*]]* sret [[RESULT:%.*]], [[B]]* [[T0]])
+ // CHECK-NEXT: br label
+ // CHECK: call void @_ZN5test31AC1Ev([[A]]* [[RESULT]])
+ // CHECK-NEXT: br label
+ // CHECK: ret void
+ return x ?: A();
+ }
+
+ A test3() {
+ // CHECK-LABEL: define void @_ZN5test35test3Ev(
+ // CHECK: [[TEMP:%.*]] = alloca [[B]],
+ // CHECK-NEXT: call void @_ZN5test312test3_helperEv([[B]]* sret [[TEMP]])
+ // CHECK-NEXT: [[BOOL:%.*]] = call zeroext i1 @_ZN5test31BcvbEv([[B]]* [[TEMP]])
+ // CHECK-NEXT: br i1 [[BOOL]]
+ // CHECK: call void @_ZN5test31BcvNS_1AEEv([[A]]* sret [[RESULT:%.*]], [[B]]* [[TEMP]])
+ // CHECK-NEXT: br label
+ // CHECK: call void @_ZN5test31AC1Ev([[A]]* [[RESULT]])
+ // CHECK-NEXT: br label
+ // CHECK: call void @_ZN5test31BD1Ev([[B]]* [[TEMP]])
+ // CHECK-NEXT: ret void
+ extern B test3_helper();
+ return test3_helper() ?: A();
+ }
+
+}
+
+namespace test4 {
+ // Make sure this doesn't crash.
+ void f() {
+ const int a = 10, b = 20;
+ const int *c = &(a ?: b);
+ }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/conditional-temporaries.cpp b/src/llvm-project/clang/test/CodeGenCXX/conditional-temporaries.cpp
new file mode 100644
index 0000000..48c9117
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/conditional-temporaries.cpp
@@ -0,0 +1,205 @@
+// REQUIRES: amdgpu-registered-target
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -O2 -disable-llvm-passes | FileCheck %s --check-prefixes=CHECK,CHECK-NOOPT
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -O2 | FileCheck %s --check-prefixes=CHECK,CHECK-OPT
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=amdgcn-amd-amdhsa -O2 | FileCheck %s --check-prefixes=CHECK,CHECK-OPT
+
+namespace {
+
+static int ctorcalls;
+static int dtorcalls;
+
+struct A {
+ A() : i(0) { ctorcalls++; }
+ ~A() { dtorcalls++; }
+ int i;
+
+ friend const A& operator<<(const A& a, int n) {
+ return a;
+ }
+};
+
+void g(int) { }
+void g(const A&) { }
+
+void f1(bool b) {
+ g(b ? A().i : 0);
+ g(b || A().i);
+ g(b && A().i);
+ g(b ? A() << 1 : A() << 2);
+}
+
+struct Checker {
+ Checker() {
+ f1(true);
+ f1(false);
+ }
+};
+
+Checker c;
+
+}
+
+// CHECK-OPT-LABEL: define i32 @_Z12getCtorCallsv()
+int getCtorCalls() {
+ // CHECK-OPT: ret i32 5
+ return ctorcalls;
+}
+
+// CHECK-OPT-LABEL: define i32 @_Z12getDtorCallsv()
+int getDtorCalls() {
+ // CHECK-OPT: ret i32 5
+ return dtorcalls;
+}
+
+// CHECK-OPT-LABEL: define zeroext i1 @_Z7successv()
+bool success() {
+ // CHECK-OPT: ret i1 true
+ return ctorcalls == dtorcalls;
+}
+
+struct X { ~X(); int f(); };
+int g(int, int, int);
+// CHECK-LABEL: @_Z16lifetime_nontriv
+int lifetime_nontriv(bool cond) {
+ // CHECK-NOOPT: store i1 false,
+ // CHECK-NOOPT: store i1 false,
+ // CHECK-NOOPT: store i1 false,
+ // CHECK-NOOPT: store i1 false,
+ // CHECK-NOOPT: store i1 false,
+ // CHECK-NOOPT: store i1 false,
+ // CHECK-NOOPT: br i1
+ //
+ // CHECK-NOOPT: call void @llvm.lifetime.start
+ // CHECK-NOOPT: store i1 true,
+ // CHECK-NOOPT: store i1 true,
+ // CHECK-NOOPT: call i32 @_ZN1X1fEv(
+ // CHECK-NOOPT: call void @llvm.lifetime.start
+ // CHECK-NOOPT: store i1 true,
+ // CHECK-NOOPT: store i1 true,
+ // CHECK-NOOPT: call i32 @_ZN1X1fEv(
+ // CHECK-NOOPT: call void @llvm.lifetime.start
+ // CHECK-NOOPT: store i1 true,
+ // CHECK-NOOPT: store i1 true,
+ // CHECK-NOOPT: call i32 @_ZN1X1fEv(
+ // CHECK-NOOPT: call i32 @_Z1giii(
+ // CHECK-NOOPT: br label
+ //
+ // CHECK-NOOPT: call i32 @_Z1giii(i32 1, i32 2, i32 3)
+ // CHECK-NOOPT: br label
+ //
+ // CHECK-NOOPT: load i1,
+ // CHECK-NOOPT: br i1
+ // CHECK-NOOPT: call void @_ZN1XD1Ev(
+ // CHECK-NOOPT: br label
+ //
+ // CHECK-NOOPT: load i1,
+ // CHECK-NOOPT: br i1
+ // CHECK-NOOPT: call void @llvm.lifetime.end
+ // CHECK-NOOPT: br label
+ //
+ // CHECK-NOOPT: load i1,
+ // CHECK-NOOPT: br i1
+ // CHECK-NOOPT: call void @_ZN1XD1Ev(
+ // CHECK-NOOPT: br label
+ //
+ // CHECK-NOOPT: load i1,
+ // CHECK-NOOPT: br i1
+ // CHECK-NOOPT: call void @llvm.lifetime.end
+ // CHECK-NOOPT: br label
+ //
+ // CHECK-NOOPT: load i1,
+ // CHECK-NOOPT: br i1
+ // CHECK-NOOPT: call void @_ZN1XD1Ev(
+ // CHECK-NOOPT: br label
+ //
+ // CHECK-NOOPT: load i1,
+ // CHECK-NOOPT: br i1
+ // CHECK-NOOPT: call void @llvm.lifetime.end
+ // CHECK-NOOPT: br label
+ //
+ // CHECK-NOOPT: ret
+
+ // CHECK-OPT: br i1
+ //
+ // CHECK-OPT: call void @llvm.lifetime.start
+ // CHECK-OPT: call i32 @_ZN1X1fEv(
+ // CHECK-OPT: call void @llvm.lifetime.start
+ // CHECK-OPT: call i32 @_ZN1X1fEv(
+ // CHECK-OPT: call void @llvm.lifetime.start
+ // CHECK-OPT: call i32 @_ZN1X1fEv(
+ // CHECK-OPT: call i32 @_Z1giii(
+ // CHECK-OPT: call void @_ZN1XD1Ev(
+ // CHECK-OPT: call void @llvm.lifetime.end
+ // CHECK-OPT: call void @_ZN1XD1Ev(
+ // CHECK-OPT: call void @llvm.lifetime.end
+ // CHECK-OPT: call void @_ZN1XD1Ev(
+ // CHECK-OPT: call void @llvm.lifetime.end
+ // CHECK-OPT: br label
+ return cond ? g(X().f(), X().f(), X().f()) : g(1, 2, 3);
+}
+
+struct Y { int f(); };
+int g(int, int, int);
+// CHECK-LABEL: @_Z13lifetime_triv
+int lifetime_triv(bool cond) {
+ // CHECK-NOOPT: call void @llvm.lifetime.start
+ // CHECK-NOOPT: call void @llvm.lifetime.start
+ // CHECK-NOOPT: call void @llvm.lifetime.start
+ // CHECK-NOOPT: br i1
+ //
+ // CHECK-NOOPT: call i32 @_ZN1Y1fEv(
+ // CHECK-NOOPT: call i32 @_ZN1Y1fEv(
+ // CHECK-NOOPT: call i32 @_ZN1Y1fEv(
+ // CHECK-NOOPT: call i32 @_Z1giii(
+ // CHECK-NOOPT: br label
+ //
+ // CHECK-NOOPT: call i32 @_Z1giii(i32 1, i32 2, i32 3)
+ // CHECK-NOOPT: br label
+ //
+ // CHECK-NOOPT: call void @llvm.lifetime.end
+ // CHECK-NOOPT-NOT: br
+ // CHECK-NOOPT: call void @llvm.lifetime.end
+ // CHECK-NOOPT-NOT: br
+ // CHECK-NOOPT: call void @llvm.lifetime.end
+ //
+ // CHECK-NOOPT: ret
+
+ // FIXME: LLVM isn't smart enough to remove the lifetime markers from the
+ // g(1, 2, 3) path here.
+
+ // CHECK-OPT: call void @llvm.lifetime.start
+ // CHECK-OPT: call void @llvm.lifetime.start
+ // CHECK-OPT: call void @llvm.lifetime.start
+ // CHECK-OPT: br i1
+ //
+ // CHECK-OPT: call i32 @_ZN1Y1fEv(
+ // CHECK-OPT: call i32 @_ZN1Y1fEv(
+ // CHECK-OPT: call i32 @_ZN1Y1fEv(
+ // CHECK-OPT: call i32 @_Z1giii(
+ // CHECK-OPT: br label
+ //
+ // CHECK-OPT: call void @llvm.lifetime.end
+ // CHECK-OPT: call void @llvm.lifetime.end
+ // CHECK-OPT: call void @llvm.lifetime.end
+ return cond ? g(Y().f(), Y().f(), Y().f()) : g(1, 2, 3);
+}
+
+struct Z { ~Z() {} int f(); };
+int g(int, int, int);
+// CHECK-LABEL: @_Z22lifetime_nontriv_empty
+int lifetime_nontriv_empty(bool cond) {
+ // CHECK-OPT: br i1
+ //
+ // CHECK-OPT: call void @llvm.lifetime.start
+ // CHECK-OPT: call i32 @_ZN1Z1fEv(
+ // CHECK-OPT: call void @llvm.lifetime.start
+ // CHECK-OPT: call i32 @_ZN1Z1fEv(
+ // CHECK-OPT: call void @llvm.lifetime.start
+ // CHECK-OPT: call i32 @_ZN1Z1fEv(
+ // CHECK-OPT: call i32 @_Z1giii(
+ // CHECK-OPT: call void @llvm.lifetime.end
+ // CHECK-OPT: call void @llvm.lifetime.end
+ // CHECK-OPT: call void @llvm.lifetime.end
+ // CHECK-OPT: br label
+ return cond ? g(Z().f(), Z().f(), Z().f()) : g(1, 2, 3);
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/const-base-cast.cpp b/src/llvm-project/clang/test/CodeGenCXX/const-base-cast.cpp
new file mode 100644
index 0000000..bb08b9d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/const-base-cast.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s
+
+// Check that the following construct, which is similar to one which occurs
+// in Firefox, is folded correctly.
+struct A { char x; };
+struct B { char y; };
+struct C : A,B {};
+unsigned char x = ((char*)(B*)(C*)0x1000) - (char*)0x1000;
+
+// CHECK: @x = {{(dso_local )?}}global i8 1
diff --git a/src/llvm-project/clang/test/CodeGenCXX/const-global-linkage.cpp b/src/llvm-project/clang/test/CodeGenCXX/const-global-linkage.cpp
new file mode 100644
index 0000000..2ec64cf
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/const-global-linkage.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
+
+const int x = 10;
+const int y = 20;
+const volatile int z = 30;
+// CHECK-NOT: @x
+// CHECK: @z = {{(dso_local )?}}constant i32 30
+// CHECK: @_ZL1y = internal constant i32 20
+const int& b() { return y; }
+
+const char z1[] = "asdf";
+const char z2[] = "zxcv";
+const volatile char z3[] = "zxcv";
+// CHECK-NOT: @z1
+// CHECK: @z3 = {{(dso_local )?}}constant
+// CHECK: @_ZL2z2 = internal constant
+const char* b2() { return z2; }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/const-init-cxx11.cpp b/src/llvm-project/clang/test/CodeGenCXX/const-init-cxx11.cpp
new file mode 100644
index 0000000..9fb4ba5
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/const-init-cxx11.cpp
@@ -0,0 +1,611 @@
+// RUN: %clang_cc1 -w -fmerge-all-constants -triple x86_64-elf-gnu -emit-llvm -o - %s -std=c++11 | FileCheck %s
+
+// FIXME: The padding in all these objects should be zero-initialized.
+namespace StructUnion {
+ struct A {
+ int n;
+ double d;
+ union U {
+ constexpr U(int x) : x(x) {}
+ constexpr U(const char *y) : y(y) {}
+ int x;
+ const char *y;
+ } u;
+
+ constexpr A(int n, double d, int x) : n(n), d(d), u(x) {}
+ constexpr A(int n, double d, const char *y) : n(n), d(d), u(y) {}
+ };
+
+ // CHECK: @_ZN11StructUnion1aE = constant {{.*}} { i32 1, double 2.000000e+00, {{.*}} { i32 3, [4 x i8] undef } }
+ extern constexpr A a(1, 2.0, 3);
+
+ // CHECK: @_ZN11StructUnion1bE = constant {{.*}} { i32 4, double 5.000000e+00, {{.*}} { i8* getelementptr inbounds ([6 x i8], [6 x i8]* @{{.*}}, i32 0, i32 0) } }
+ extern constexpr A b(4, 5, "hello");
+
+ struct B {
+ int n;
+ };
+
+ // CHECK: @_ZN11StructUnion1cE = global {{.*}} zeroinitializer
+ // CHECK: @_ZN11StructUnion2c2E = global {{.*}} zeroinitializer
+ B c;
+ B c2 = B();
+
+ // CHECK: @_ZN11StructUnion1dE = global {{.*}} zeroinitializer
+ B d[10];
+
+ struct C {
+ constexpr C() : c(0) {}
+ int c;
+ };
+
+ // CHECK: @_ZN11StructUnion1eE = global {{.*}} zeroinitializer
+ C e[10];
+
+ struct D {
+ constexpr D() : d(5) {}
+ int d;
+ };
+
+ // CHECK: @_ZN11StructUnion1fE = global {{.*}} { i32 5 }
+ D f;
+
+ union E {
+ int a;
+ void *b = &f;
+ };
+
+ // CHECK: @_ZN11StructUnion1gE = global {{.*}} @_ZN11StructUnion1fE
+ E g;
+
+ // CHECK: @_ZN11StructUnion1hE = global {{.*}} @_ZN11StructUnion1fE
+ E h = E();
+}
+
+namespace BaseClass {
+ template<typename T, unsigned> struct X : T {};
+ struct C { char c = 1; };
+ template<unsigned... Ns> struct Cs : X<C,Ns>... {};
+ struct N { int n = 3; };
+ struct D { double d = 4.0; };
+
+ template<typename ...Ts>
+ struct Test : Ts... { constexpr Test() : Ts()..., n(5) {} int n; };
+
+ using Test1 = Test<N, C, Cs<1,2>, D, X<C,1>>;
+ // CHECK: @_ZN9BaseClass2t1E = constant {{.*}} { i32 3, i8 1, i8 1, i8 1, double 4.000000e+00, i8 1, i32 5 }, align 8
+ extern constexpr Test1 t1 = Test1();
+
+ struct DN : D, N {};
+ struct DND : DN, X<D,0> {};
+ struct DNN : DN, X<N,0> {};
+ // CHECK: @_ZN9BaseClass3dndE = constant {{.*}} { double 4.000000e+00, i32 3, double 4.000000e+00 }
+ extern constexpr DND dnd = DND();
+ // Note, N subobject is laid out in DN subobject's tail padding.
+ // CHECK: @_ZN9BaseClass3dnnE = constant {{.*}} { double 4.000000e+00, i32 3, i32 3 }
+ extern constexpr DNN dnn = DNN();
+
+ struct E {};
+ struct Test2 : X<E,0>, X<E,1>, X<E,2>, X<E,3> {};
+ // CHECK: @_ZN9BaseClass2t2E = constant {{.*}} undef
+ extern constexpr Test2 t2 = Test2();
+
+ struct __attribute((packed)) PackedD { double y = 2; };
+ struct Test3 : C, PackedD { constexpr Test3() {} };
+ // CHECK: @_ZN9BaseClass2t3E = constant <{ i8, double }> <{ i8 1, double 2.000000e+00 }>
+ extern constexpr Test3 t3 = Test3();
+}
+
+namespace Array {
+ // CHECK: @_ZN5Array3arrE = constant [2 x i32] [i32 4, i32 0]
+ extern constexpr int arr[2] = { 4 };
+
+ // CHECK: @_ZN5Array1cE = constant [6 x [4 x i8]] [{{.*}} c"foo\00", [4 x i8] c"a\00\00\00", [4 x i8] c"bar\00", [4 x i8] c"xyz\00", [4 x i8] c"b\00\00\00", [4 x i8] c"123\00"]
+ extern constexpr char c[6][4] = { "foo", "a", { "bar" }, { 'x', 'y', 'z' }, { "b" }, '1', '2', '3' };
+
+ // CHECK: @_ZN5Array2ucE = constant [4 x i8] c"foo\00"
+ extern constexpr unsigned char uc[] = { "foo" };
+
+ struct C { constexpr C() : n(5) {} int n, m = 3 * n + 1; };
+ // CHECK: @_ZN5Array5ctorsE = constant [3 x {{.*}}] [{{.*}} { i32 5, i32 16 }, {{.*}} { i32 5, i32 16 }, {{.*}} { i32 5, i32 16 }]
+ extern const C ctors[3];
+ constexpr C ctors[3];
+
+ // CHECK: @_ZN5Array1dE = constant {{.*}} { [2 x i32] [i32 1, i32 2], [3 x i32] [i32 3, i32 4, i32 5] }
+ struct D { int n[2]; int m[3]; } extern constexpr d = { 1, 2, 3, 4, 5 };
+
+ struct E {
+ char c[4];
+ char d[4];
+ constexpr E() : c("foo"), d("x") {}
+ };
+ // CHECK: @_ZN5Array1eE = constant {{.*}} { [4 x i8] c"foo\00", [4 x i8] c"x\00\00\00" }
+ extern constexpr E e = E();
+
+ // PR13290
+ struct F { constexpr F() : n(4) {} int n; };
+ // CHECK: @_ZN5Array2f1E = global {{.*}} zeroinitializer
+ F f1[1][1][0] = { };
+ // CHECK: @_ZN5Array2f2E = global {{.* i32 4 .* i32 4 .* i32 4 .* i32 4 .* i32 4 .* i32 4 .* i32 4 .* i32 4}}
+ F f2[2][2][2] = { };
+}
+
+namespace MemberPtr {
+ struct B1 {
+ int a, b;
+ virtual void f();
+ void g();
+ };
+ struct B2 {
+ int c, d;
+ virtual void h();
+ void i();
+ };
+ struct C : B1 {
+ int e;
+ virtual void j();
+ void k();
+ };
+ struct D : C, B2 {
+ int z;
+ virtual void l();
+ void m();
+ };
+
+ // CHECK: @_ZN9MemberPtr2daE = constant i64 8
+ // CHECK: @_ZN9MemberPtr2dbE = constant i64 12
+ // CHECK: @_ZN9MemberPtr2dcE = constant i64 32
+ // CHECK: @_ZN9MemberPtr2ddE = constant i64 36
+ // CHECK: @_ZN9MemberPtr2deE = constant i64 16
+ // CHECK: @_ZN9MemberPtr2dzE = constant i64 40
+ extern constexpr int (D::*da) = &B1::a;
+ extern constexpr int (D::*db) = &C::b;
+ extern constexpr int (D::*dc) = &B2::c;
+ extern constexpr int (D::*dd) = &D::d;
+ extern constexpr int (D::*de) = &C::e;
+ extern constexpr int (D::*dz) = &D::z;
+
+ // CHECK: @_ZN9MemberPtr2baE = constant i64 8
+ // CHECK: @_ZN9MemberPtr2bbE = constant i64 12
+ // CHECK: @_ZN9MemberPtr2bcE = constant i64 8
+ // CHECK: @_ZN9MemberPtr2bdE = constant i64 12
+ // CHECK: @_ZN9MemberPtr2beE = constant i64 16
+ // CHECK: @_ZN9MemberPtr3b1zE = constant i64 40
+ // CHECK: @_ZN9MemberPtr3b2zE = constant i64 16
+ extern constexpr int (B1::*ba) = (int(B1::*))&B1::a;
+ extern constexpr int (B1::*bb) = (int(B1::*))&C::b;
+ extern constexpr int (B2::*bc) = (int(B2::*))&B2::c;
+ extern constexpr int (B2::*bd) = (int(B2::*))&D::d;
+ extern constexpr int (B1::*be) = (int(B1::*))&C::e;
+ extern constexpr int (B1::*b1z) = (int(B1::*))&D::z;
+ extern constexpr int (B2::*b2z) = (int(B2::*))&D::z;
+
+ // CHECK: @_ZN9MemberPtr2dfE = constant {{.*}} { i64 1, i64 0 }
+ // CHECK: @_ZN9MemberPtr2dgE = constant {{.*}} { i64 {{.*}}2B11gEv{{.*}}, i64 0 }
+ // CHECK: @_ZN9MemberPtr2dhE = constant {{.*}} { i64 1, i64 24 }
+ // CHECK: @_ZN9MemberPtr2diE = constant {{.*}} { i64 {{.*}}2B21iEv{{.*}}, i64 24 }
+ // CHECK: @_ZN9MemberPtr2djE = constant {{.*}} { i64 9, i64 0 }
+ // CHECK: @_ZN9MemberPtr2dkE = constant {{.*}} { i64 {{.*}}1C1kEv{{.*}}, i64 0 }
+ // CHECK: @_ZN9MemberPtr2dlE = constant {{.*}} { i64 17, i64 0 }
+ // CHECK: @_ZN9MemberPtr2dmE = constant {{.*}} { i64 {{.*}}1D1mEv{{.*}}, i64 0 }
+ extern constexpr void (D::*df)() = &C::f;
+ extern constexpr void (D::*dg)() = &B1::g;
+ extern constexpr void (D::*dh)() = &B2::h;
+ extern constexpr void (D::*di)() = &D::i;
+ extern constexpr void (D::*dj)() = &C::j;
+ extern constexpr void (D::*dk)() = &C::k;
+ extern constexpr void (D::*dl)() = &D::l;
+ extern constexpr void (D::*dm)() = &D::m;
+
+ // CHECK: @_ZN9MemberPtr2bfE = constant {{.*}} { i64 1, i64 0 }
+ // CHECK: @_ZN9MemberPtr2bgE = constant {{.*}} { i64 {{.*}}2B11gEv{{.*}}, i64 0 }
+ // CHECK: @_ZN9MemberPtr2bhE = constant {{.*}} { i64 1, i64 0 }
+ // CHECK: @_ZN9MemberPtr2biE = constant {{.*}} { i64 {{.*}}2B21iEv{{.*}}, i64 0 }
+ // CHECK: @_ZN9MemberPtr2bjE = constant {{.*}} { i64 9, i64 0 }
+ // CHECK: @_ZN9MemberPtr2bkE = constant {{.*}} { i64 {{.*}}1C1kEv{{.*}}, i64 0 }
+ // CHECK: @_ZN9MemberPtr3b1lE = constant {{.*}} { i64 17, i64 0 }
+ // CHECK: @_ZN9MemberPtr3b1mE = constant {{.*}} { i64 {{.*}}1D1mEv{{.*}}, i64 0 }
+ // CHECK: @_ZN9MemberPtr3b2lE = constant {{.*}} { i64 17, i64 -24 }
+ // CHECK: @_ZN9MemberPtr3b2mE = constant {{.*}} { i64 {{.*}}1D1mEv{{.*}}, i64 -24 }
+ extern constexpr void (B1::*bf)() = (void(B1::*)())&C::f;
+ extern constexpr void (B1::*bg)() = (void(B1::*)())&B1::g;
+ extern constexpr void (B2::*bh)() = (void(B2::*)())&B2::h;
+ extern constexpr void (B2::*bi)() = (void(B2::*)())&D::i;
+ extern constexpr void (B1::*bj)() = (void(B1::*)())&C::j;
+ extern constexpr void (B1::*bk)() = (void(B1::*)())&C::k;
+ extern constexpr void (B1::*b1l)() = (void(B1::*)())&D::l;
+ extern constexpr void (B1::*b1m)() = (void(B1::*)())&D::m;
+ extern constexpr void (B2::*b2l)() = (void(B2::*)())&D::l;
+ extern constexpr void (B2::*b2m)() = (void(B2::*)())&D::m;
+}
+
+namespace LiteralReference {
+ struct Lit {
+ constexpr Lit() : n(5) {}
+ int n;
+ };
+
+ // This creates a non-const temporary and binds a reference to it.
+ // CHECK: @[[TEMP:.*]] = internal global {{.*}} { i32 5 }, align 4
+ // CHECK: @_ZN16LiteralReference3litE = constant {{.*}} @[[TEMP]], align 8
+ const Lit &lit = Lit();
+
+ // This creates a const temporary as part of the reference initialization.
+ // CHECK: @[[TEMP:.*]] = internal constant {{.*}} { i32 5 }, align 4
+ // CHECK: @_ZN16LiteralReference4lit2E = constant {{.*}} @[[TEMP]], align 8
+ const Lit &lit2 = {};
+
+ struct A { int &&r1; const int &&r2; };
+ struct B { A &&a1; const A &&a2; };
+ B b = { { 0, 1 }, { 2, 3 } };
+ // CHECK: @[[TEMP0:.*]] = internal global i32 0, align 4
+ // CHECK: @[[TEMP1:.*]] = internal constant i32 1, align 4
+ // CHECK: @[[TEMPA1:.*]] = internal global {{.*}} { i32* @[[TEMP0]], i32* @[[TEMP1]] }, align 8
+ // CHECK: @[[TEMP2:.*]] = internal global i32 2, align 4
+ // CHECK: @[[TEMP3:.*]] = internal constant i32 3, align 4
+ // CHECK: @[[TEMPA2:.*]] = internal constant {{.*}} { i32* @[[TEMP2]], i32* @[[TEMP3]] }, align 8
+ // CHECK: @_ZN16LiteralReference1bE = global {{.*}} { {{.*}}* @[[TEMPA1]], {{.*}}* @[[TEMPA2]] }, align 8
+
+ struct Subobj {
+ int a, b, c;
+ };
+ // CHECK: @[[TEMP:.*]] = internal global {{.*}} { i32 1, i32 2, i32 3 }, align 4
+ // CHECK: @_ZN16LiteralReference2soE = constant {{.*}} (i8* getelementptr {{.*}} @[[TEMP]]{{.*}}, i64 4)
+ constexpr int &&so = Subobj{ 1, 2, 3 }.b;
+
+ struct Dummy { int padding; };
+ struct Derived : Dummy, Subobj {
+ constexpr Derived() : Dummy{200}, Subobj{4, 5, 6} {}
+ };
+ using ConstDerived = const Derived;
+ // CHECK: @[[TEMPCOMMA:.*]] = internal constant {{.*}} { i32 200, i32 4, i32 5, i32 6 }
+ // CHECK: @_ZN16LiteralReference5commaE = constant {{.*}} getelementptr {{.*}} @[[TEMPCOMMA]]{{.*}}, i64 8)
+ constexpr const int &comma = (1, (2, ConstDerived{}).b);
+
+ // CHECK: @[[TEMPDERIVED:.*]] = internal global {{.*}} { i32 200, i32 4, i32 5, i32 6 }
+ // CHECK: @_ZN16LiteralReference4baseE = constant {{.*}} getelementptr {{.*}} @[[TEMPDERIVED]]{{.*}}, i64 4)
+ constexpr Subobj &&base = Derived{};
+
+ // CHECK: @_ZN16LiteralReference7derivedE = constant {{.*}} @[[TEMPDERIVED]]
+ constexpr Derived &derived = static_cast<Derived&>(base);
+}
+
+namespace NonLiteralConstexpr {
+ constexpr int factorial(int n) {
+ return n ? factorial(n-1) * n : 1;
+ }
+ extern void f(int *p);
+
+ struct NonTrivialDtor {
+ constexpr NonTrivialDtor() : n(factorial(5)), p(&n) {}
+ ~NonTrivialDtor() {
+ f(p);
+ }
+
+ int n;
+ int *p;
+ };
+ static_assert(!__is_literal(NonTrivialDtor), "");
+ // CHECK: @_ZN19NonLiteralConstexpr3ntdE = global {{.*}} { i32 120, i32* getelementptr
+ NonTrivialDtor ntd;
+
+ struct VolatileMember {
+ constexpr VolatileMember() : n(5) {}
+ volatile int n;
+ };
+ static_assert(!__is_literal(VolatileMember), "");
+ // CHECK: @_ZN19NonLiteralConstexpr2vmE = global {{.*}} { i32 5 }
+ VolatileMember vm;
+
+ struct Both {
+ constexpr Both() : n(10) {}
+ ~Both();
+ volatile int n;
+ };
+ // CHECK: @_ZN19NonLiteralConstexpr1bE = global {{.*}} { i32 10 }
+ Both b;
+
+ void StaticVars() {
+ // CHECK: @_ZZN19NonLiteralConstexpr10StaticVarsEvE3ntd = {{.*}} { i32 120, i32* getelementptr {{.*}}
+ // CHECK: @_ZGVZN19NonLiteralConstexpr10StaticVarsEvE3ntd =
+ static NonTrivialDtor ntd;
+ // CHECK: @_ZZN19NonLiteralConstexpr10StaticVarsEvE2vm = {{.*}} { i32 5 }
+ // CHECK-NOT: @_ZGVZN19NonLiteralConstexpr10StaticVarsEvE2vm =
+ static VolatileMember vm;
+ // CHECK: @_ZZN19NonLiteralConstexpr10StaticVarsEvE1b = {{.*}} { i32 10 }
+ // CHECK: @_ZGVZN19NonLiteralConstexpr10StaticVarsEvE1b =
+ static Both b;
+ }
+}
+
+// PR12067
+namespace VirtualMembers {
+ struct A {
+ constexpr A(double d) : d(d) {}
+ virtual void f();
+ double d;
+ };
+ struct B : A {
+ constexpr B() : A(2.0), c{'h', 'e', 'l', 'l', 'o'} {}
+ constexpr B(int n) : A(n), c{'w', 'o', 'r', 'l', 'd'} {}
+ virtual void g();
+ char c[5];
+ };
+ struct C {
+ constexpr C() : n(64) {}
+ int n;
+ };
+ struct D : C, A, B {
+ constexpr D() : A(1.0), B(), s(5) {}
+ short s;
+ };
+ struct E : D, B {
+ constexpr E() : B(3), c{'b','y','e'} {}
+ char c[3];
+ };
+ // CHECK: @_ZN14VirtualMembers1eE = global { i8**, double, i32, i8**, double, [5 x i8], i16, i8**, double, [5 x i8], [3 x i8] } { i8** getelementptr inbounds ({ [3 x i8*], [4 x i8*], [4 x i8*] }, { [3 x i8*], [4 x i8*], [4 x i8*] }* @_ZTVN14VirtualMembers1EE, i32 0, inrange i32 0, i32 2), double 1.000000e+00, i32 64, i8** getelementptr inbounds ({ [3 x i8*], [4 x i8*], [4 x i8*] }, { [3 x i8*], [4 x i8*], [4 x i8*] }* @_ZTVN14VirtualMembers1EE, i32 0, inrange i32 1, i32 2), double 2.000000e+00, [5 x i8] c"hello", i16 5, i8** getelementptr inbounds ({ [3 x i8*], [4 x i8*], [4 x i8*] }, { [3 x i8*], [4 x i8*], [4 x i8*] }* @_ZTVN14VirtualMembers1EE, i32 0, inrange i32 2, i32 2), double 3.000000e+00, [5 x i8] c"world", [3 x i8] c"bye" }
+ E e;
+
+ struct nsMemoryImpl {
+ virtual void f();
+ };
+ // CHECK: @_ZN14VirtualMembersL13sGlobalMemoryE = internal global { i8** } { i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN14VirtualMembers12nsMemoryImplE, i32 0, inrange i32 0, i32 2) }
+ __attribute__((used))
+ static nsMemoryImpl sGlobalMemory;
+
+ template<class T>
+ struct TemplateClass {
+ constexpr TemplateClass() : t{42} {}
+ virtual void templateMethod() {}
+
+ T t;
+ };
+ // CHECK: @_ZN14VirtualMembers1tE = global { i8**, i32 } { i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN14VirtualMembers13TemplateClassIiEE, i32 0, inrange i32 0, i32 2), i32 42 }
+ TemplateClass<int> t;
+}
+
+namespace PR13273 {
+ struct U {
+ int t;
+ U() = default;
+ };
+
+ struct S : U {
+ S() = default;
+ };
+
+ // CHECK: @_ZN7PR132731sE = {{.*}} zeroinitializer
+ extern const S s {};
+}
+
+namespace ArrayTemporary {
+ struct A { const int (&x)[3]; };
+ struct B { const A (&x)[2]; };
+ // CHECK: @[[A1:_ZGRN14ArrayTemporary1bE.*]] = internal constant [3 x i32] [i32 1, i32 2, i32 3]
+ // CHECK: @[[A2:_ZGRN14ArrayTemporary1bE.*]] = internal constant [3 x i32] [i32 4, i32 5, i32 6]
+ // CHECK: @[[ARR:_ZGRN14ArrayTemporary1bE.*]] = internal constant [2 x {{.*}}] [{{.*}} { [3 x i32]* @[[A1]] }, {{.*}} { [3 x i32]* @[[A2]] }]
+ // CHECK: @[[B:_ZGRN14ArrayTemporary1bE.*]] = internal global {{.*}} { [2 x {{.*}}]* @[[ARR]] }
+ // CHECK: @_ZN14ArrayTemporary1bE = constant {{.*}}* @[[B]]
+ B &&b = { { { { 1, 2, 3 } }, { { 4, 5, 6 } } } };
+}
+
+namespace UnemittedTemporaryDecl {
+ constexpr int &&ref = 0;
+ extern constexpr int &ref2 = ref;
+ // CHECK: @_ZGRN22UnemittedTemporaryDecl3refE_ = internal global i32 0
+
+ // FIXME: This declaration should not be emitted -- it isn't odr-used.
+ // CHECK: @_ZN22UnemittedTemporaryDecl3refE
+
+ // CHECK: @_ZN22UnemittedTemporaryDecl4ref2E = constant i32* @_ZGRN22UnemittedTemporaryDecl3refE_
+}
+
+// CHECK: @_ZZN12LocalVarInit3aggEvE1a = internal constant {{.*}} i32 101
+// CHECK: @_ZZN12LocalVarInit4ctorEvE1a = internal constant {{.*}} i32 102
+// CHECK: @__const._ZN12LocalVarInit8mutable_Ev.a = private unnamed_addr constant {{.*}} i32 103
+// CHECK: @_ZGRN33ClassTemplateWithStaticDataMember1SIvE1aE_ = linkonce_odr constant i32 5, comdat
+// CHECK: @_ZN33ClassTemplateWithStaticDataMember3useE = constant i32* @_ZGRN33ClassTemplateWithStaticDataMember1SIvE1aE_
+// CHECK: @_ZGRN39ClassTemplateWithHiddenStaticDataMember1SIvE1aE_ = linkonce_odr hidden constant i32 5, comdat
+// CHECK: @_ZN39ClassTemplateWithHiddenStaticDataMember3useE = constant i32* @_ZGRN39ClassTemplateWithHiddenStaticDataMember1SIvE1aE_
+// CHECK: @_ZGRZN20InlineStaticConstRef3funEvE1i_ = linkonce_odr constant i32 10, comdat
+
+// Constant initialization tests go before this point,
+// dynamic initialization tests go after.
+
+// We must emit a constant initializer for NonLiteralConstexpr::ntd, but also
+// emit an initializer to register its destructor.
+// CHECK: define {{.*}}cxx_global_var_init{{.*}}
+// CHECK-NOT: NonLiteralConstexpr
+// CHECK: call {{.*}}cxa_atexit{{.*}} @_ZN19NonLiteralConstexpr14NonTrivialDtorD1Ev {{.*}} @_ZN19NonLiteralConstexpr3ntdE
+// CHECK-NEXT: ret void
+
+// We don't need to emit any dynamic initialization for NonLiteralConstexpr::vm.
+// CHECK-NOT: NonLiteralConstexpr2vm
+
+// We must emit a constant initializer for NonLiteralConstexpr::b, but also
+// emit an initializer to register its destructor.
+// CHECK: define {{.*}}cxx_global_var_init{{.*}}
+// CHECK-NOT: NonLiteralConstexpr
+// CHECK: call {{.*}}cxa_atexit{{.*}} @_ZN19NonLiteralConstexpr4BothD1Ev {{.*}} @_ZN19NonLiteralConstexpr1bE
+// CHECK-NEXT: ret void
+
+// CHECK: define {{.*}}NonLiteralConstexpr10StaticVars
+// CHECK-NOT: }
+// CHECK: call {{.*}}cxa_atexit{{.*}}@_ZN19NonLiteralConstexpr14NonTrivialDtorD1Ev
+// CHECK-NOT: }
+// CHECK: call {{.*}}cxa_atexit{{.*}}@_ZN19NonLiteralConstexpr4BothD1Ev
+
+// PR12848: Don't emit dynamic initializers for local constexpr variables.
+namespace LocalVarInit {
+ constexpr int f(int n) { return n; }
+ struct Agg { int k; };
+ struct Ctor { constexpr Ctor(int n) : k(n) {} int k; };
+ struct Mutable { constexpr Mutable(int n) : k(n) {} mutable int k; };
+
+ // CHECK: define {{.*}} @_ZN12LocalVarInit6scalarEv
+ // CHECK-NOT: call
+ // CHECK: store i32 100,
+ // CHECK-NOT: call
+ // CHECK: ret i32 100
+ int scalar() { constexpr int a = { f(100) }; return a; }
+
+ // CHECK: define {{.*}} @_ZN12LocalVarInit3aggEv
+ // CHECK-NOT: call
+ // CHECK: ret i32 101
+ int agg() { constexpr Agg a = { f(101) }; return a.k; }
+
+ // CHECK: define {{.*}} @_ZN12LocalVarInit4ctorEv
+ // CHECK-NOT: call
+ // CHECK: ret i32 102
+ int ctor() { constexpr Ctor a = { f(102) }; return a.k; }
+
+ // CHECK: define {{.*}} @_ZN12LocalVarInit8mutable_Ev
+ // CHECK-NOT: call
+ // CHECK: call {{.*}}memcpy{{.*}} @__const._ZN12LocalVarInit8mutable_Ev.a
+ // CHECK-NOT: call
+ // Can't fold return value due to 'mutable'.
+ // CHECK-NOT: ret i32 103
+ // CHECK: }
+ int mutable_() { constexpr Mutable a = { f(103) }; return a.k; }
+}
+
+namespace CrossFuncLabelDiff {
+ // Make sure we refuse to constant-fold the variable b.
+ constexpr long a(bool x) { return x ? 0 : (long)&&lbl + (0 && ({lbl: 0;})); }
+ void test() { static long b = (long)&&lbl - a(false); lbl: return; }
+ // CHECK: sub nsw i64 ptrtoint (i8* blockaddress(@_ZN18CrossFuncLabelDiff4testEv, {{.*}}) to i64),
+ // CHECK: store i64 {{.*}}, i64* @_ZZN18CrossFuncLabelDiff4testEvE1b, align 8
+}
+
+// PR12012
+namespace VirtualBase {
+ struct B {};
+ struct D : virtual B {};
+ D d;
+ // CHECK: call {{.*}}@_ZN11VirtualBase1DC1Ev
+
+ template<typename T> struct X : T {
+ constexpr X() : T() {}
+ };
+ X<D> x;
+ // CHECK: call {{.*}}@_ZN11VirtualBase1XINS_1DEEC1Ev
+}
+
+// PR12145
+namespace Unreferenced {
+ int n;
+ constexpr int *p = &n;
+ // We must not emit a load of 'p' here, since it's not odr-used.
+ int q = *p;
+ // CHECK-NOT: _ZN12Unreferenced1pE
+ // CHECK: = load i32, i32* @_ZN12Unreferenced1nE
+ // CHECK-NEXT: store i32 {{.*}}, i32* @_ZN12Unreferenced1qE
+ // CHECK-NOT: _ZN12Unreferenced1pE
+
+ // Technically, we are not required to substitute variables of reference types
+ // initialized by constant expressions, because the special case for odr-use
+ // of variables in [basic.def.odr]p2 only applies to objects. But we do so
+ // anyway.
+
+ constexpr int &r = n;
+ // CHECK-NOT: _ZN12Unreferenced1rE
+ int s = r;
+
+ const int t = 1;
+ const int &rt = t;
+ int f(int);
+ int u = f(rt);
+ // CHECK: call i32 @_ZN12Unreferenced1fEi(i32 1)
+}
+
+namespace InitFromConst {
+ template<typename T> void consume(T);
+
+ const bool b = true;
+ const int n = 5;
+ constexpr double d = 4.3;
+
+ struct S { int n = 7; S *p = 0; };
+ constexpr S s = S();
+ const S &r = s;
+ constexpr const S *p = &r;
+ constexpr int S::*mp = &S::n;
+ constexpr int a[3] = { 1, 4, 9 };
+
+ void test() {
+ // CHECK: call void @_ZN13InitFromConst7consumeIbEEvT_(i1 zeroext true)
+ consume(b);
+
+ // CHECK: call void @_ZN13InitFromConst7consumeIiEEvT_(i32 5)
+ consume(n);
+
+ // CHECK: call void @_ZN13InitFromConst7consumeIdEEvT_(double 4.300000e+00)
+ consume(d);
+
+ // CHECK: call void @_ZN13InitFromConst7consumeIRKNS_1SEEEvT_(%"struct.InitFromConst::S"* dereferenceable({{[0-9]+}}) @_ZN13InitFromConstL1sE)
+ consume<const S&>(s);
+
+ // CHECK: call void @_ZN13InitFromConst7consumeIRKNS_1SEEEvT_(%"struct.InitFromConst::S"* dereferenceable({{[0-9]+}}) @_ZN13InitFromConstL1sE)
+ consume<const S&>(r);
+
+ // CHECK: call void @_ZN13InitFromConst7consumeIPKNS_1SEEEvT_(%"struct.InitFromConst::S"* @_ZN13InitFromConstL1sE)
+ consume(p);
+
+ // CHECK: call void @_ZN13InitFromConst7consumeIMNS_1SEiEEvT_(i64 0)
+ consume(mp);
+
+ // CHECK: call void @_ZN13InitFromConst7consumeIPKiEEvT_(i32* getelementptr inbounds ([3 x i32], [3 x i32]* @_ZN13InitFromConstL1aE, i32 0, i32 0))
+ consume(a);
+ }
+}
+
+namespace Null {
+ decltype(nullptr) null();
+ // CHECK: call {{.*}} @_ZN4Null4nullEv(
+ int *p = null();
+ struct S {};
+ // CHECK: call {{.*}} @_ZN4Null4nullEv(
+ int S::*q = null();
+}
+
+namespace InlineStaticConstRef {
+ inline const int &fun() {
+ static const int &i = 10;
+ return i;
+ // CHECK: ret i32* @_ZGRZN20InlineStaticConstRef3funEvE1i_
+ }
+ const int &use = fun();
+}
+
+namespace ClassTemplateWithStaticDataMember {
+ template <typename T>
+ struct S {
+ static const int &a;
+ };
+ template <typename T>
+ const int &S<T>::a = 5;
+ const int &use = S<void>::a;
+}
+
+namespace ClassTemplateWithHiddenStaticDataMember {
+ template <typename T>
+ struct S {
+ __attribute__((visibility("hidden"))) static const int &a;
+ };
+ template <typename T>
+ const int &S<T>::a = 5;
+ const int &use = S<void>::a;
+}
+
+namespace ClassWithStaticConstexprDataMember {
+struct X {
+ static constexpr const char &p = 'c';
+};
+
+// CHECK: @_ZGRN34ClassWithStaticConstexprDataMember1X1pE_
+const char *f() { return &X::p; }
+}
+
+// VirtualMembers::TemplateClass::templateMethod() must be defined in this TU,
+// not just declared.
+// CHECK: define linkonce_odr void @_ZN14VirtualMembers13TemplateClassIiE14templateMethodEv(%"struct.VirtualMembers::TemplateClass"* %this)
diff --git a/src/llvm-project/clang/test/CodeGenCXX/const-init-cxx1y.cpp b/src/llvm-project/clang/test/CodeGenCXX/const-init-cxx1y.cpp
new file mode 100644
index 0000000..c10cde8
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/const-init-cxx1y.cpp
@@ -0,0 +1,87 @@
+// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin -emit-llvm -o - %s -std=c++1y | FileCheck %s
+// expected-no-diagnostics
+
+struct A {
+ constexpr A() : n(1) {}
+ ~A();
+ int n;
+};
+struct B : A {
+ A a[3];
+ constexpr B() {
+ ++a[0].n;
+ a[1].n += 2;
+ a[2].n = n + a[1].n;
+ }
+};
+B b;
+
+// CHECK: @b = global {{.*}} i32 1, {{.*}} { i32 2 }, {{.*}} { i32 3 }, {{.*}} { i32 4 }
+// CHECK-NOT: _ZN1BC
+
+namespace ModifyStaticTemporary {
+ struct A { int &&temporary; int x; };
+ constexpr int f(int &r) { r *= 9; return r - 12; }
+ A a = { 6, f(a.temporary) };
+ // CHECK: @_ZGRN21ModifyStaticTemporary1aE_ = internal global i32 54
+ // CHECK: @_ZN21ModifyStaticTemporary1aE = global {{.*}} i32* @_ZGRN21ModifyStaticTemporary1aE_, i32 42
+
+ A b = { 7, ++b.temporary };
+ // CHECK: @_ZGRN21ModifyStaticTemporary1bE_ = internal global i32 8
+ // CHECK: @_ZN21ModifyStaticTemporary1bE = global {{.*}} i32* @_ZGRN21ModifyStaticTemporary1bE_, i32 8
+
+ // Can't emit all of 'c' as a constant here, so emit the initial value of
+ // 'c.temporary', not the value as modified by the partial evaluation within
+ // the initialization of 'c.x'.
+ A c = { 10, (++c.temporary, b.x) };
+ // CHECK: @_ZGRN21ModifyStaticTemporary1cE_ = internal global i32 10
+ // CHECK: @_ZN21ModifyStaticTemporary1cE = global {{.*}} zeroinitializer
+}
+
+// CHECK: @_ZGRN28VariableTemplateWithConstRef1iIvEE_ = linkonce_odr constant i32 5, align 4
+// CHECK: @_ZN28VariableTemplateWithConstRef3useE = constant i32* @_ZGRN28VariableTemplateWithConstRef1iIvEE_
+namespace VariableTemplateWithConstRef {
+ template <typename T>
+ const int &i = 5;
+ const int &use = i<void>;
+}
+
+// CHECK: @_ZGRN34HiddenVariableTemplateWithConstRef1iIvEE_ = linkonce_odr hidden constant i32 5, align 4
+// CHECK: @_ZN34HiddenVariableTemplateWithConstRef3useE = constant i32* @_ZGRN34HiddenVariableTemplateWithConstRef1iIvEE_
+namespace HiddenVariableTemplateWithConstRef {
+ template <typename T>
+ __attribute__((visibility("hidden"))) const int &i = 5;
+ const int &use = i<void>;
+}
+
+// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE1_ = linkonce_odr constant i32 1
+// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE0_ = linkonce_odr global {{.*}} { i32* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE1_ }
+// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE3_ = linkonce_odr constant i32 2
+// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE2_ = linkonce_odr global {{.*}} { i32* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE3_ }
+// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE5_ = linkonce_odr constant i32 3
+// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE4_ = linkonce_odr global {{.*}} { i32* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE5_ }
+// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE7_ = linkonce_odr constant i32 4
+// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE6_ = linkonce_odr global {{.*}} { i32* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE7_ }
+// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE_ = linkonce_odr global %"struct.VariableTemplateWithPack::S" { {{.*}}* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE0_, {{.*}}* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE2_, {{.*}}* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE4_, {{.*}}* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE6_ }
+// CHECK: @_ZN24VariableTemplateWithPack1pE = global {{.*}} @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE_
+namespace VariableTemplateWithPack {
+ struct A {
+ const int &r;
+ };
+ struct S {
+ A &&a, &&b, &&c, &&d;
+ };
+ template <int... N>
+ S &&s = {A{N}...};
+ S *p = &s<1, 2, 3, 4>;
+}
+
+// CHECK: __cxa_atexit({{.*}} @_ZN1BD1Ev {{.*}} @b
+
+// CHECK: define
+// CHECK-NOT: @_ZGRN21ModifyStaticTemporary1cE_
+// CHECK: store {{.*}} @_ZGRN21ModifyStaticTemporary1cE_, {{.*}} @_ZN21ModifyStaticTemporary1cE
+// CHECK: add
+// CHECK: store
+// CHECK: load {{.*}} @_ZN21ModifyStaticTemporary1bE
+// CHECK: store {{.*}} @_ZN21ModifyStaticTemporary1cE
diff --git a/src/llvm-project/clang/test/CodeGenCXX/const-init.cpp b/src/llvm-project/clang/test/CodeGenCXX/const-init.cpp
new file mode 100644
index 0000000..f5c9dae
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/const-init.cpp
@@ -0,0 +1,92 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -std=c++98 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -std=c++11 -o - %s | FileCheck %s
+
+// CHECK: @a = global i32 10
+int a = 10;
+// CHECK: @ar = constant i32* @a
+int &ar = a;
+
+void f();
+// CHECK: @fr = constant void ()* @_Z1fv
+void (&fr)() = f;
+
+struct S { int& a; };
+// CHECK: @s = global %struct.S { i32* @a }
+S s = { a };
+
+// PR5581
+namespace PR5581 {
+class C {
+public:
+ enum { e0, e1 };
+ unsigned f;
+};
+
+// CHECK: @_ZN6PR55812g0E = global %"class.PR5581::C" { i32 1 }
+C g0 = { C::e1 };
+}
+
+namespace test2 {
+ struct A {
+#if __cplusplus <= 199711L
+ static const double d = 1.0;
+ static const float f = d / 2;
+#else
+ static constexpr double d = 1.0;
+ static constexpr float f = d / 2;
+#endif
+ static int g();
+ } a;
+
+ // 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
+ // CHECK: @_ZN5test22t2E = global double* @_ZN5test21A1d
+ // CHECK: @_ZN5test22t3E = global {{.*}} @_ZN5test21A1g
+ double t0 = A::d;
+ double t1[] = { A::d, A::f };
+ const double *t2 = &a.d;
+ int (*t3)() = &a.g;
+}
+
+// We don't expect to fold this in the frontend, but make sure it doesn't crash.
+// CHECK: @PR9558 = global float 0.000000e+0
+float PR9558 = reinterpret_cast<const float&>("asd");
+
+// An initialized const automatic variable cannot be promoted to a constant
+// global if it has a mutable member.
+struct MutableMember {
+ mutable int n;
+};
+int writeToMutable() {
+ // CHECK-NOT: {{.*}}MM{{.*}} = {{.*}}constant
+ const MutableMember MM = { 0 };
+ return ++MM.n;
+}
+
+// Make sure we don't try to fold this in the frontend; the backend can't
+// handle it.
+// CHECK: @PR11705 = global i128 0
+__int128_t PR11705 = (__int128_t)&PR11705;
+
+// Make sure we don't try to fold this either.
+// CHECK: @_ZZ23UnfoldableAddrLabelDiffvE1x = internal global i128 0
+void UnfoldableAddrLabelDiff() { static __int128_t x = (long)&&a-(long)&&b; a:b:return;}
+
+// But make sure we do fold this.
+// CHECK: @_ZZ21FoldableAddrLabelDiffvE1x = internal global i64 sub (i64 ptrtoint (i8* blockaddress(@_Z21FoldableAddrLabelDiffv
+void FoldableAddrLabelDiff() { static long x = (long)&&a-(long)&&b; a:b:return;}
+
+// CHECK: @i = constant i32* bitcast (float* @PR9558 to i32*)
+int &i = reinterpret_cast<int&>(PR9558);
+
+int arr[2];
+// CHECK: @pastEnd = constant i32* bitcast (i8* getelementptr (i8, i8* bitcast ([2 x i32]* @arr to i8*), i64 8) to i32*)
+int &pastEnd = arr[2];
+
+struct X {
+ long n : 8;
+};
+long k;
+X x = {(long)&k};
+// CHECK: store i8 ptrtoint (i64* @k to i8), i8* getelementptr inbounds (%struct.X, %struct.X* @x, i32 0, i32 0)
diff --git a/src/llvm-project/clang/test/CodeGenCXX/constructor-alias.cpp b/src/llvm-project/clang/test/CodeGenCXX/constructor-alias.cpp
new file mode 100644
index 0000000..ee2e57b
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/constructor-alias.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -emit-llvm -triple mipsel--linux-gnu -mconstructor-aliases -o - %s | FileCheck %s
+
+// The target attribute code used to get confused with aliases. Make sure
+// we don't crash when an alias is used.
+
+struct B {
+ B();
+};
+B::B() {
+}
+
+// CHECK: @_ZN1BC1Ev = unnamed_addr alias void (%struct.B*), void (%struct.B*)* @_ZN1BC2Ev
diff --git a/src/llvm-project/clang/test/CodeGenCXX/constructor-attr.cpp b/src/llvm-project/clang/test/CodeGenCXX/constructor-attr.cpp
new file mode 100644
index 0000000..ec27ed2
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/constructor-attr.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: @llvm.global_ctors
+
+// PR6521
+void bar();
+struct Foo {
+ // CHECK-LABEL: define linkonce_odr {{.*}}void @_ZN3Foo3fooEv
+ static void foo() __attribute__((constructor)) {
+ bar();
+ }
+};
diff --git a/src/llvm-project/clang/test/CodeGenCXX/constructor-conversion.cpp b/src/llvm-project/clang/test/CodeGenCXX/constructor-conversion.cpp
new file mode 100644
index 0000000..bace54f
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/constructor-conversion.cpp
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm %s -o - | \
+// RUN: FileCheck %s
+// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -emit-llvm %s -o - | \
+// RUN: FileCheck %s
+
+extern "C" int printf(...);
+
+class X { // ...
+public:
+ X(int) : iX(2), fX(2.3) , name("HELLO\n") { }
+
+ X(const char* arg, int ix=0) { iX = ix; fX = 6.0; name = arg+ix; }
+ X(): iX(100), fX(1.2) {}
+ int iX;
+ float fX;
+ const char *name;
+ void pr(void) {
+ printf("iX = %d fX = %f name = %s\n", iX, fX, name);
+ }
+};
+
+void g(X arg) {
+ arg.pr();
+}
+
+void f(X arg) {
+ X a = 1; // a = X(1)
+
+ a.pr();
+
+ X b = "Jessie"; // b=X("Jessie",0)
+
+ b.pr();
+
+
+ a = 2; // a = X(2)
+
+ a.pr();
+}
+
+
+int main() {
+ X x;
+ f(x);
+ g(3); // g(X(3))
+}
+
+// CHECK: call void @_ZN1XC1Ei
+// CHECK: call void @_ZN1XC1EPKci
+// CHECK: call void @_ZN1XC1Ev
diff --git a/src/llvm-project/clang/test/CodeGenCXX/constructor-convert.cpp b/src/llvm-project/clang/test/CodeGenCXX/constructor-convert.cpp
new file mode 100644
index 0000000..7feeaa9
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/constructor-convert.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s
+
+// PR5775
+class Twine {
+public:
+ Twine(const char *Str) { }
+};
+
+static void error(const Twine &Message) {}
+
+template<typename>
+struct opt_storage {
+ void f() {
+ error("cl::location(x) specified more than once!");
+ }
+};
+
+void f(opt_storage<int> o) {
+ o.f();
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/constructor-default-arg.cpp b/src/llvm-project/clang/test/CodeGenCXX/constructor-default-arg.cpp
new file mode 100644
index 0000000..98a5864
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/constructor-default-arg.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm %s -o - | \
+// RUN: FileCheck %s
+// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -emit-llvm %s -o - | \
+// RUN: FileCheck %s
+
+extern "C" int printf(...);
+
+
+struct C {
+ C() : iC(6) {}
+ int iC;
+};
+
+int foo() {
+ return 6;
+};
+
+class X { // ...
+public:
+ X(int) {}
+ X(const X&, int i = 1, int j = 2, int k = foo()) {
+ printf("X(const X&, %d, %d, %d)\n", i, j, k);
+ }
+};
+
+int main() {
+ X a(1);
+ X b(a, 2);
+ X c = b;
+ X d(a, 5, 6);
+}
+
+// CHECK: call void @_ZN1XC1ERKS_iii
+// CHECK: call void @_ZN1XC1ERKS_iii
+// CHECK: call void @_ZN1XC1ERKS_iii
diff --git a/src/llvm-project/clang/test/CodeGenCXX/constructor-destructor-return-this.cpp b/src/llvm-project/clang/test/CodeGenCXX/constructor-destructor-return-this.cpp
new file mode 100644
index 0000000..f6450e2
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/constructor-destructor-return-this.cpp
@@ -0,0 +1,141 @@
+//RUN: %clang_cc1 %s -emit-llvm -o - -triple=i686-unknown-linux | FileCheck --check-prefix=CHECKGEN %s
+//RUN: %clang_cc1 %s -emit-llvm -o - -triple=thumbv7-apple-ios6.0 -target-abi apcs-gnu | FileCheck --check-prefix=CHECKARM %s
+//RUN: %clang_cc1 %s -emit-llvm -o - -triple=thumbv7-apple-ios5.0 -target-abi apcs-gnu | FileCheck --check-prefix=CHECKIOS5 %s
+//RUN: %clang_cc1 %s -emit-llvm -o - -triple=wasm32-unknown-unknown \
+//RUN: | FileCheck --check-prefix=CHECKARM %s
+//RUN: %clang_cc1 %s -emit-llvm -o - -triple=i386-pc-win32 -fno-rtti | FileCheck --check-prefix=CHECKMS %s
+// FIXME: these tests crash on the bots when run with -triple=x86_64-pc-win32
+
+// Make sure we attach the 'returned' attribute to the 'this' parameter of
+// constructors and destructors which return this (and only these cases)
+
+class A {
+public:
+ A();
+ virtual ~A();
+
+private:
+ int x_;
+};
+
+class B : public A {
+public:
+ B(int *i);
+ virtual ~B();
+
+private:
+ int *i_;
+};
+
+B::B(int *i) : i_(i) { }
+B::~B() { }
+
+// CHECKGEN-LABEL: define void @_ZN1BC2EPi(%class.B* %this, i32* %i)
+// CHECKGEN-LABEL: define void @_ZN1BC1EPi(%class.B* %this, i32* %i)
+// CHECKGEN-LABEL: define void @_ZN1BD2Ev(%class.B* %this)
+// CHECKGEN-LABEL: define void @_ZN1BD1Ev(%class.B* %this)
+
+// CHECKARM-LABEL: define %class.B* @_ZN1BC2EPi(%class.B* returned %this, i32* %i)
+// CHECKARM-LABEL: define %class.B* @_ZN1BC1EPi(%class.B* returned %this, i32* %i)
+// CHECKARM-LABEL: define %class.B* @_ZN1BD2Ev(%class.B* returned %this)
+// CHECKARM-LABEL: define %class.B* @_ZN1BD1Ev(%class.B* returned %this)
+
+// CHECKIOS5-LABEL: define %class.B* @_ZN1BC2EPi(%class.B* %this, i32* %i)
+// CHECKIOS5-LABEL: define %class.B* @_ZN1BC1EPi(%class.B* %this, i32* %i)
+// CHECKIOS5-LABEL: define %class.B* @_ZN1BD2Ev(%class.B* %this)
+// CHECKIOS5-LABEL: define %class.B* @_ZN1BD1Ev(%class.B* %this)
+
+// CHECKMS-LABEL: define dso_local x86_thiscallcc %class.B* @"??0B@@QAE@PAH@Z"(%class.B* returned %this, i32* %i)
+// CHECKMS-LABEL: define dso_local x86_thiscallcc void @"??1B@@UAE@XZ"(%class.B* %this)
+
+class C : public A, public B {
+public:
+ C(int *i, char *c);
+ virtual ~C();
+private:
+ char *c_;
+};
+
+C::C(int *i, char *c) : B(i), c_(c) { }
+C::~C() { }
+
+// CHECKGEN-LABEL: define void @_ZN1CC2EPiPc(%class.C* %this, i32* %i, i8* %c)
+// CHECKGEN-LABEL: define void @_ZN1CC1EPiPc(%class.C* %this, i32* %i, i8* %c)
+// CHECKGEN-LABEL: define void @_ZN1CD2Ev(%class.C* %this)
+// CHECKGEN-LABEL: define void @_ZN1CD1Ev(%class.C* %this)
+// CHECKGEN-LABEL: define void @_ZThn8_N1CD1Ev(%class.C* %this)
+// CHECKGEN-LABEL: define void @_ZN1CD0Ev(%class.C* %this)
+// CHECKGEN-LABEL: define void @_ZThn8_N1CD0Ev(%class.C* %this)
+
+// CHECKARM-LABEL: define %class.C* @_ZN1CC2EPiPc(%class.C* returned %this, i32* %i, i8* %c)
+// CHECKARM-LABEL: define %class.C* @_ZN1CC1EPiPc(%class.C* returned %this, i32* %i, i8* %c)
+// CHECKARM-LABEL: define %class.C* @_ZN1CD2Ev(%class.C* returned %this)
+// CHECKARM-LABEL: define %class.C* @_ZN1CD1Ev(%class.C* returned %this)
+// CHECKARM-LABEL: define %class.C* @_ZThn8_N1CD1Ev(%class.C* %this)
+// CHECKARM-LABEL: define void @_ZN1CD0Ev(%class.C* %this)
+// CHECKARM-LABEL: define void @_ZThn8_N1CD0Ev(%class.C* %this)
+
+// CHECKIOS5-LABEL: define %class.C* @_ZN1CC2EPiPc(%class.C* %this, i32* %i, i8* %c)
+// CHECKIOS5-LABEL: define %class.C* @_ZN1CC1EPiPc(%class.C* %this, i32* %i, i8* %c)
+// CHECKIOS5-LABEL: define %class.C* @_ZN1CD2Ev(%class.C* %this)
+// CHECKIOS5-LABEL: define %class.C* @_ZN1CD1Ev(%class.C* %this)
+// CHECKIOS5-LABEL: define %class.C* @_ZThn8_N1CD1Ev(%class.C* %this)
+// CHECKIOS5-LABEL: define void @_ZN1CD0Ev(%class.C* %this)
+// CHECKIOS5-LABEL: define void @_ZThn8_N1CD0Ev(%class.C* %this)
+
+// CHECKMS-LABEL: define dso_local x86_thiscallcc %class.C* @"??0C@@QAE@PAHPAD@Z"(%class.C* returned %this, i32* %i, i8* %c)
+// CHECKMS-LABEL: define dso_local x86_thiscallcc void @"??1C@@UAE@XZ"(%class.C* %this)
+
+class D : public virtual A {
+public:
+ D();
+ ~D();
+};
+
+D::D() { }
+D::~D() { }
+
+// CHECKGEN-LABEL: define void @_ZN1DC2Ev(%class.D* %this, i8** %vtt)
+// CHECKGEN-LABEL: define void @_ZN1DC1Ev(%class.D* %this)
+// CHECKGEN-LABEL: define void @_ZN1DD2Ev(%class.D* %this, i8** %vtt)
+// CHECKGEN-LABEL: define void @_ZN1DD1Ev(%class.D* %this)
+
+// CHECKARM-LABEL: define %class.D* @_ZN1DC2Ev(%class.D* returned %this, i8** %vtt)
+// CHECKARM-LABEL: define %class.D* @_ZN1DC1Ev(%class.D* returned %this)
+// CHECKARM-LABEL: define %class.D* @_ZN1DD2Ev(%class.D* returned %this, i8** %vtt)
+// CHECKARM-LABEL: define %class.D* @_ZN1DD1Ev(%class.D* returned %this)
+
+// CHECKIOS5-LABEL: define %class.D* @_ZN1DC2Ev(%class.D* %this, i8** %vtt)
+// CHECKIOS5-LABEL: define %class.D* @_ZN1DC1Ev(%class.D* %this)
+// CHECKIOS5-LABEL: define %class.D* @_ZN1DD2Ev(%class.D* %this, i8** %vtt)
+// CHECKIOS5-LABEL: define %class.D* @_ZN1DD1Ev(%class.D* %this)
+
+// CHECKMS-LABEL: define dso_local x86_thiscallcc %class.D* @"??0D@@QAE@XZ"(%class.D* returned %this, i32 %is_most_derived)
+// CHECKMS-LABEL: define dso_local x86_thiscallcc void @"??1D@@UAE@XZ"(%class.D* %this)
+
+class E {
+public:
+ E();
+ virtual ~E();
+};
+
+E* gete();
+
+void test_destructor() {
+ const E& e1 = E();
+ E* e2 = gete();
+ e2->~E();
+}
+
+// CHECKARM-LABEL: define void @_Z15test_destructorv()
+
+// Verify that virtual calls to destructors are not marked with a 'returned'
+// this parameter at the call site...
+// CHECKARM: [[VFN:%.*]] = getelementptr inbounds %class.E* (%class.E*)*, %class.E* (%class.E*)**
+// CHECKARM: [[THUNK:%.*]] = load %class.E* (%class.E*)*, %class.E* (%class.E*)** [[VFN]]
+// CHECKARM: call %class.E* [[THUNK]](%class.E* %
+
+// ...but static calls create declarations with 'returned' this
+// CHECKARM: {{%.*}} = call %class.E* @_ZN1ED1Ev(%class.E* %
+
+// CHECKARM: declare %class.E* @_ZN1ED1Ev(%class.E* returned)
diff --git a/src/llvm-project/clang/test/CodeGenCXX/constructor-direct-call.cpp b/src/llvm-project/clang/test/CodeGenCXX/constructor-direct-call.cpp
new file mode 100644
index 0000000..bcddc0f
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/constructor-direct-call.cpp
@@ -0,0 +1,59 @@
+// RUN: %clang_cc1 -triple i686-pc-mingw32 -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* align 4 %{{.*}}, i8* align 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 x86_thiscallcc void @_ZN5Test2C1Ev(%class.Test2* %var)
+ Test2 var;
+
+ // CHECK-NEXT: call x86_thiscallcc void @_ZN5Test2C1Ev(%class.Test2* %var)
+ var.Test2::Test2();
+
+ // CHECK: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %{{.*}}, i8* align 4 %{{.*}}, i32 8, 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 x86_thiscallcc void @_ZN5Test3C1Ev(%class.Test3* %var)
+ Test3 var;
+
+ // CHECK-NEXT: call x86_thiscallcc void @_ZN5Test3C1Ev(%class.Test3* %var2)
+ Test3 var2;
+
+ // CHECK-NEXT: call x86_thiscallcc void @_ZN5Test3C1Ev(%class.Test3* %var)
+ var.Test3::Test3();
+
+ // CHECK-NEXT: call x86_thiscallcc void @_ZN5Test3C1ERKS_(%class.Test3* %var, %class.Test3* dereferenceable({{[0-9]+}}) %var2)
+ var.Test3::Test3(var2);
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/constructor-for-array-members.cpp b/src/llvm-project/clang/test/CodeGenCXX/constructor-for-array-members.cpp
new file mode 100644
index 0000000..8ea7eac
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/constructor-for-array-members.cpp
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm %s -o - | \
+// RUN: FileCheck %s
+// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -emit-llvm %s -o - | \
+// RUN: FileCheck %s
+
+extern "C" int printf(...);
+
+int i = 1234;
+float vf = 1.00;
+
+struct S {
+ S() : iS(i++), f1(vf++) {printf("S::S()\n");}
+ ~S(){printf("S::~S(iS = %d f1 = %f)\n", iS, f1); }
+ int iS;
+ float f1;
+};
+
+struct M {
+ double dM;
+ S ARR_S[3];
+ void pr() {
+ for (int i = 0; i < 3; i++)
+ printf("ARR_S[%d].iS = %d ARR_S[%d].f1 = %f\n", i, ARR_S[i].iS, i, ARR_S[i].f1);
+
+ for (int i = 0; i < 2; i++)
+ for (int j = 0; j < 3; j++)
+ for (int k = 0; k < 4; k++)
+ printf("MULTI_ARR[%d][%d][%d].iS = %d MULTI_ARR[%d][%d][%d].f1 = %f\n",
+ i,j,k, MULTI_ARR[i][j][k].iS, i,j,k, MULTI_ARR[i][j][k].f1);
+
+ }
+
+ S MULTI_ARR[2][3][4];
+};
+
+int main() {
+ M m1;
+ m1.pr();
+}
+
+// CHECK: call void @_ZN1SC1Ev
diff --git a/src/llvm-project/clang/test/CodeGenCXX/constructor-init-reference.cpp b/src/llvm-project/clang/test/CodeGenCXX/constructor-init-reference.cpp
new file mode 100644
index 0000000..61f426d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/constructor-init-reference.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
+
+int x;
+struct A {
+ int& y;
+ A() : y(x) {}
+};
+A z;
+// CHECK: store i32* @x, i32**
diff --git a/src/llvm-project/clang/test/CodeGenCXX/constructor-init.cpp b/src/llvm-project/clang/test/CodeGenCXX/constructor-init.cpp
new file mode 100644
index 0000000..fe15ccf
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/constructor-init.cpp
@@ -0,0 +1,241 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 %s -emit-llvm -o %t
+// RUN: FileCheck %s < %t
+// RUN: FileCheck -check-prefix=CHECK-PR10720 %s < %t
+
+extern "C" int printf(...);
+
+struct M {
+ M() { printf("M()\n"); }
+ M(int i) { iM = i; printf("M(%d)\n", i); }
+ int iM;
+ void MPR() {printf("iM = %d\n", iM); };
+};
+
+struct P {
+ P() { printf("P()\n"); }
+ P(int i) { iP = i; printf("P(%d)\n", i); }
+ int iP;
+ void PPR() {printf("iP = %d\n", iP); };
+};
+
+struct Q {
+ Q() { printf("Q()\n"); }
+ Q(int i) { iQ = i; printf("Q(%d)\n", i); }
+ int iQ;
+ void QPR() {printf("iQ = %d\n", iQ); };
+};
+
+struct N : M , P, Q {
+ N() : f1(1.314), P(2000), ld(00.1234+f1), M(1000), Q(3000),
+ d1(3.4567), i1(1234), m1(100) { printf("N()\n"); }
+ M m1;
+ M m2;
+ float f1;
+ int i1;
+ float d1;
+ void PR() {
+ printf("f1 = %f d1 = %f i1 = %d ld = %f \n", f1,d1,i1, ld);
+ MPR();
+ PPR();
+ QPR();
+ printf("iQ = %d\n", iQ);
+ printf("iP = %d\n", iP);
+ printf("iM = %d\n", iM);
+ // FIXME. We don't yet support this syntax.
+ // printf("iQ = %d\n", (*this).iQ);
+ printf("iQ = %d\n", this->iQ);
+ printf("iP = %d\n", this->iP);
+ printf("iM = %d\n", this->iM);
+ }
+ float ld;
+ float ff;
+ M arr_m[3];
+ P arr_p[1][3];
+ Q arr_q[2][3][4];
+};
+
+int main() {
+ M m1;
+
+ N n1;
+ n1.PR();
+}
+
+// PR5826
+template <class T> struct A {
+ A() {}
+ A(int) {}
+ A(const A&) {}
+ ~A() {}
+ operator int() {return 0;}
+};
+
+// CHECK-LABEL: define void @_Z1fv()
+void f() {
+ // CHECK: call void @_ZN1AIsEC1Ei
+ A<short> a4 = 97;
+
+ // CHECK-NEXT: store i32 17
+ int i = 17;
+
+ // CHECK-NEXT: call void @_ZN1AIsED1Ev
+ // CHECK-NOT: call void @_ZN1AIsED1Ev
+ // 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-LABEL: define void @_ZN10InitVTable1BC2Ev(%"struct.InitVTable::B"* %this) unnamed_addr
+ // CHECK: [[T0:%.*]] = bitcast [[B:%.*]]* [[THIS:%.*]] to i32 (...)***
+ // CHECK-NEXT: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN10InitVTable1BE, i32 0, inrange i32 0, i32 2) to i32 (...)**), i32 (...)*** [[T0]]
+ // CHECK: [[VTBL:%.*]] = load i32 ([[B]]*)**, i32 ([[B]]*)*** {{%.*}}
+ // CHECK-NEXT: [[FNP:%.*]] = getelementptr inbounds i32 ([[B]]*)*, i32 ([[B]]*)** [[VTBL]], i64 0
+ // CHECK-NEXT: [[FN:%.*]] = load i32 ([[B]]*)*, 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 i32 (...)***
+ // CHECK-NEXT: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN10InitVTable1BE, i32 0, inrange i32 0, i32 2) to i32 (...)**), i32 (...)*** [[T0]]
+ // CHECK-NEXT: ret void
+ B::B() : A(foo()) {}
+
+ // CHECK-LABEL: 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 i32 (...)***
+ // CHECK-NEXT: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN10InitVTable1BE, i32 0, inrange i32 0, i32 2) to i32 (...)**), i32 (...)*** [[T0]]
+ // CHECK-NEXT: ret void
+ B::B(int x) : A(x + 5) {}
+}
+
+namespace rdar9694300 {
+ struct X {
+ int x;
+ };
+
+ // CHECK-LABEL: define void @_ZN11rdar96943001fEv
+ void f() {
+ // CHECK: alloca
+ X x;
+ // CHECK-NEXT: [[I:%.*]] = alloca i32
+ // CHECK-NEXT: store i32 17, i32* [[I]]
+ int i = 17;
+ // CHECK-NEXT: ret void
+ }
+}
+
+// Check that we emit a zero initialization step for list-value-initialization
+// which calls a trivial default constructor.
+namespace PR13273 {
+ struct U {
+ int t;
+ U() = default;
+ };
+
+ struct S : U {
+ S() = default;
+ };
+
+ // CHECK: define {{.*}}@_ZN7PR132731fEv(
+ int f() {
+ // CHECK-NOT: }
+ // CHECK: llvm.memset{{.*}}i8 0
+ return (new S{})->t;
+ }
+}
+
+template<typename T>
+struct X {
+ X(const X &);
+
+ T *start;
+ T *end;
+};
+
+template<typename T> struct X;
+
+// Make sure that the instantiated constructor initializes start and
+// end properly.
+// CHECK-LABEL: define linkonce_odr void @_ZN1XIiEC2ERKS0_(%struct.X* %this, %struct.X* dereferenceable({{[0-9]+}}) %other) unnamed_addr
+// CHECK: {{store.*null}}
+// CHECK: {{store.*null}}
+// CHECK: ret
+template<typename T>
+X<T>::X(const X &other) : start(0), end(0) { }
+
+X<int> get_X(X<int> x) { return x; }
+
+namespace PR10720 {
+ struct X {
+ X(const X&);
+ X(X&&);
+ X& operator=(const X&);
+ X& operator=(X&&);
+ ~X();
+ };
+
+ struct pair2 {
+ X second[4];
+
+ // CHECK-PR10720: define linkonce_odr {{.*}} @_ZN7PR107205pair2aSERKS0_
+ // CHECK-PR10720: load
+ // CHECK-PR10720: icmp ne
+ // CHECK-PR10720-NEXT: br i1
+ // CHECK-PR10720: call {{.*}} @_ZN7PR107201XaSERKS0_
+ // CHECK-PR10720: ret
+ pair2 &operator=(const pair2&) = default;
+
+ // CHECK-PR10720: define linkonce_odr {{.*}} @_ZN7PR107205pair2aSEOS0_
+ // CHECK-PR10720: load
+ // CHECK-PR10720: icmp ne
+ // CHECK-PR10720-NEXT: br i1
+ // CHECK-PR10720: call {{.*}} @_ZN7PR107201XaSEOS0_
+ // CHECK-PR10720: ret
+ pair2 &operator=(pair2&&) = default;
+
+ // CHECK-PR10720-LABEL: define linkonce_odr void @_ZN7PR107204pairC2ERKS0_
+ // CHECK-PR10720-NOT: ret
+ // CHECK-PR10720: call void @llvm.memcpy
+ // CHECK-PR10720-NEXT: ret void
+
+ // CHECK-PR10720-LABEL: define linkonce_odr void @_ZN7PR107205pair2C2ERKS0_
+ // CHECK-PR10720-NOT: ret
+ // CHECK-PR10720: call void @_ZN7PR107201XC1ERKS0_
+ // CHECK-PR10720: icmp eq
+ // CHECK-PR10720-NEXT: br i1
+ // CHECK-PR10720: ret void
+
+ // CHECK-PR10720-LABEL: define linkonce_odr void @_ZN7PR107205pair2C2EOS0_
+ // CHECK-PR10720-NOT: ret
+ // CHECK-PR10720: load
+ // CHECK-PR10720: call void @_ZN7PR107201XC1EOS0_
+ // CHECK-PR10720: icmp eq
+ // CHECK-PR10720-NEXT: br i1
+ // CHECK-PR10720: ret void
+ pair2(pair2&&) = default;
+
+ pair2(const pair2&) = default;
+ };
+
+ struct pair : X { // Make the copy constructor non-trivial, so we actually generate it.
+ int second[4];
+ pair(const pair&) = default;
+ };
+
+ void foo(const pair &x, const pair2 &x2) {
+ pair y(x);
+ pair2 y2(x2);
+ pair2 y2m(static_cast<pair2&&>(y2));
+
+ y2 = x2;
+ y2m = static_cast<pair2&&>(y2);
+ }
+
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/constructor-template.cpp b/src/llvm-project/clang/test/CodeGenCXX/constructor-template.cpp
new file mode 100644
index 0000000..d1ae094
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/constructor-template.cpp
@@ -0,0 +1,54 @@
+// REQUIRES: x86-registered-target
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -S %s -o %t-64.s
+// RUN: FileCheck -check-prefix CHECK-LP64 --input-file=%t-64.s %s
+// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -S %s -o %t-32.s
+// RUN: FileCheck -check-prefix CHECK-LP32 --input-file=%t-32.s %s
+
+// PR4826
+struct A {
+ A() {
+ }
+};
+
+template<typename T>
+struct B {
+ B(T) {}
+
+ A nodes;
+};
+
+
+// PR4853
+template <typename T> class List {
+public:
+ List(){ } // List<BinomialNode<int>*>::List() remains undefined.
+ ~List() {}
+};
+
+template <typename T> class Node {
+ int i;
+public:
+ Node(){ } // Node<BinomialNode<int>*>::Node() remains undefined.
+ ~Node() {}
+};
+
+
+template<typename T> class BinomialNode : Node<BinomialNode<T>*> {
+public:
+ BinomialNode(T value) {}
+ List<BinomialNode<T>*> nodes;
+};
+
+int main() {
+ B<int> *n = new B<int>(4);
+ BinomialNode<int> *node = new BinomialNode<int>(1);
+ delete node;
+}
+
+// CHECK-LP64: __ZN4ListIP12BinomialNodeIiEED1Ev:
+// CHECK-LP64: __ZN4NodeIP12BinomialNodeIiEEC2Ev:
+// CHECK-LP64: __ZN4ListIP12BinomialNodeIiEEC1Ev:
+
+// CHECK-LP32: __ZN4ListIP12BinomialNodeIiEED1Ev:
+// CHECK-LP32: __ZN4NodeIP12BinomialNodeIiEEC2Ev:
+// CHECK-LP32: __ZN4ListIP12BinomialNodeIiEEC1Ev:
diff --git a/src/llvm-project/clang/test/CodeGenCXX/constructors.cpp b/src/llvm-project/clang/test/CodeGenCXX/constructors.cpp
new file mode 100644
index 0000000..9322c41
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/constructors.cpp
@@ -0,0 +1,170 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -emit-llvm -o - | FileCheck %s --implicit-check-not=should_not_appear_in_output --check-prefixes=CHECK,NULL-INVALID
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -emit-llvm -fno-delete-null-pointer-checks -o - | FileCheck %s --implicit-check-not=should_not_appear_in_output --check-prefixes=CHECK,NULL-VALID
+
+struct Member { int x; Member(); Member(int); Member(const Member &); };
+struct VBase { int x; VBase(); VBase(int); VBase(const VBase &); };
+
+struct ValueClass {
+ ValueClass(int x, int y) : x(x), y(y) {}
+ int x;
+ int y;
+}; // subject to ABI trickery
+
+
+
+/* Test basic functionality. */
+struct A {
+ A(struct Undeclared &);
+ A(ValueClass);
+ Member mem;
+};
+
+A::A(struct Undeclared &ref) : mem(0) {}
+
+// Check that delegation works.
+// NULL-INVALID-LABEL: define void @_ZN1AC2ER10Undeclared(%struct.A* %this, %struct.Undeclared* nonnull %ref) unnamed_addr
+// NULL-VALID-LABEL: define void @_ZN1AC2ER10Undeclared(%struct.A* %this, %struct.Undeclared* %ref) unnamed_addr
+// CHECK: call void @_ZN6MemberC1Ei(
+
+// NULL-INVALID-LABEL: define void @_ZN1AC1ER10Undeclared(%struct.A* %this, %struct.Undeclared* nonnull %ref) unnamed_addr
+// NULL-VALID-LABEL: define void @_ZN1AC1ER10Undeclared(%struct.A* %this, %struct.Undeclared* %ref) unnamed_addr
+// CHECK: call void @_ZN1AC2ER10Undeclared(
+
+A::A(ValueClass v) : mem(v.y - v.x) {}
+
+// CHECK-LABEL: define void @_ZN1AC2E10ValueClass(%struct.A* %this, i64 %v.coerce) unnamed_addr
+// CHECK: call void @_ZN6MemberC1Ei(
+
+// CHECK-LABEL: define void @_ZN1AC1E10ValueClass(%struct.A* %this, i64 %v.coerce) unnamed_addr
+// CHECK: call void @_ZN1AC2E10ValueClass(
+
+/* Test that things work for inheritance. */
+struct B : A {
+ B(struct Undeclared &);
+ Member mem;
+};
+
+B::B(struct Undeclared &ref) : A(ref), mem(1) {}
+
+// NULL-INVALID-LABEL: define void @_ZN1BC2ER10Undeclared(%struct.B* %this, %struct.Undeclared* nonnull %ref) unnamed_addr
+// NULL-VALID-LABEL: define void @_ZN1BC2ER10Undeclared(%struct.B* %this, %struct.Undeclared* %ref) unnamed_addr
+// CHECK: call void @_ZN1AC2ER10Undeclared(
+// CHECK: call void @_ZN6MemberC1Ei(
+
+// NULL-INVALID-LABEL: define void @_ZN1BC1ER10Undeclared(%struct.B* %this, %struct.Undeclared* nonnull %ref) unnamed_addr
+// NULL-VALID-LABEL: define void @_ZN1BC1ER10Undeclared(%struct.B* %this, %struct.Undeclared* %ref) unnamed_addr
+// CHECK: call void @_ZN1BC2ER10Undeclared(
+
+
+/* Test that the delegation optimization is disabled for classes with
+ virtual bases (for now). This is necessary because a vbase
+ initializer could access one of the parameter variables by
+ reference. That's a solvable problem, but let's not solve it right
+ now. */
+struct C : virtual A {
+ C(int);
+ Member mem;
+};
+C::C(int x) : A(ValueClass(x, x+1)), mem(x * x) {}
+
+// CHECK-LABEL: define void @_ZN1CC2Ei(%struct.C* %this, i8** %vtt, i32 %x) unnamed_addr
+// CHECK: call void @_ZN6MemberC1Ei(
+
+// CHECK-LABEL: define void @_ZN1CC1Ei(%struct.C* %this, i32 %x) unnamed_addr
+// CHECK: call void @_ZN10ValueClassC1Eii(
+// CHECK: call void @_ZN1AC2E10ValueClass(
+// CHECK: call void @_ZN6MemberC1Ei(
+
+
+/* Test that the delegation optimization is disabled for varargs
+ constructors. */
+struct D : A {
+ D(int, ...);
+ Member mem;
+};
+
+D::D(int x, ...) : A(ValueClass(x, x+1)), mem(x*x) {}
+
+// CHECK-LABEL: define void @_ZN1DC2Eiz(%struct.D* %this, i32 %x, ...) unnamed_addr
+// CHECK: call void @_ZN10ValueClassC1Eii(
+// CHECK: call void @_ZN1AC2E10ValueClass(
+// CHECK: call void @_ZN6MemberC1Ei(
+
+// CHECK-LABEL: define void @_ZN1DC1Eiz(%struct.D* %this, i32 %x, ...) unnamed_addr
+// CHECK: call void @_ZN10ValueClassC1Eii(
+// CHECK: call void @_ZN1AC2E10ValueClass(
+// CHECK: call void @_ZN6MemberC1Ei(
+
+// PR6622: this shouldn't crash
+namespace test0 {
+ struct A {};
+ struct B : virtual A { int x; };
+ struct C : B {};
+
+ void test(C &in) {
+ C tmp = in;
+ }
+}
+
+namespace test1 {
+ struct A { A(); void *ptr; };
+ struct B { B(); int x; A a[0]; };
+ B::B() {}
+ // CHECK-LABEL: define void @_ZN5test11BC2Ev(
+ // CHECK: [[THIS:%.*]] = load [[B:%.*]]*, [[B:%.*]]**
+ // CHECK-NEXT: ret void
+}
+
+// Ensure that we
+// a) emit the ABI-required but useless complete object and deleting destructor
+// symbols for an abstract class, and
+// b) do *not* emit references to virtual base destructors for an abstract class
+//
+// Our approach to this is to give these functions a body that simply traps.
+//
+// FIXME: We should ideally not create these symbols at all, but Clang can
+// actually generate references to them in other TUs in some cases, so we can't
+// stop emitting them without breaking ABI. See:
+//
+// https://github.com/itanium-cxx-abi/cxx-abi/issues/10
+namespace abstract {
+ // Note, the destructor of this class is not instantiated here.
+ template<typename T> struct should_not_appear_in_output {
+ ~should_not_appear_in_output() { int arr[-(int)sizeof(T)]; }
+ };
+
+ struct X { ~X(); };
+
+ struct A : virtual should_not_appear_in_output<int>, X {
+ virtual ~A() = 0;
+ };
+
+ // CHECK-LABEL: define void @_ZN8abstract1AD2Ev(
+ // CHECK: call {{.*}}@_ZN8abstract1XD2Ev(
+ // CHECK: ret
+
+ // CHECK-LABEL: define void @_ZN8abstract1AD1Ev(
+ // CHECK: call {{.*}}@llvm.trap(
+ // CHECK: unreachable
+
+ // CHECK-LABEL: define void @_ZN8abstract1AD0Ev(
+ // CHECK: call {{.*}}@llvm.trap(
+ // CHECK: unreachable
+ A::~A() {}
+
+ struct B : virtual should_not_appear_in_output<int>, X {
+ virtual void f() = 0;
+ ~B();
+ };
+
+ // CHECK-LABEL: define void @_ZN8abstract1BD2Ev(
+ // CHECK: call {{.*}}@_ZN8abstract1XD2Ev(
+ // CHECK: ret
+
+ // CHECK-LABEL: define void @_ZN8abstract1BD1Ev(
+ // CHECK: call {{.*}}@llvm.trap(
+ // CHECK: unreachable
+
+ // CHECK-NOT: @_ZN8abstract1BD0Ev(
+ B::~B() {}
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/conversion-function.cpp b/src/llvm-project/clang/test/CodeGenCXX/conversion-function.cpp
new file mode 100644
index 0000000..ec098d0
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/conversion-function.cpp
@@ -0,0 +1,120 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -S %s -o %t-64.s
+// RUN: FileCheck -check-prefix CHECK-LP64 --input-file=%t-64.s %s
+// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -S %s -o %t-32.s
+// RUN: FileCheck -check-prefix CHECK-LP32 --input-file=%t-32.s %s
+// XFAIL: *
+extern "C" int printf(...);
+struct S {
+ operator int();
+};
+
+S::operator int() {
+ return 10;
+}
+
+int f(S s) {
+ return s;
+}
+
+class X { // ...
+ public: operator int() { printf("operator int()\n"); return iX; }
+ public: operator float() { printf("operator float()\n"); return fX; }
+ X() : iX(100), fX(1.234) {}
+ int iX;
+ float fX;
+};
+
+X x;
+
+struct Z {
+ operator X() { printf("perator X()\n"); x.iX += iZ; x.fX += fZ; return x; }
+ int iZ;
+ float fZ;
+ Z() : iZ(1), fZ(1.00) {}
+};
+
+Z z;
+
+class Y { // ...
+ public: operator Z(){printf("perator Z()\n"); return z; }
+};
+
+Y y;
+
+int count=0;
+class O { // ...
+public:
+ operator int(){ return ++iO; }
+ O() : iO(count++) {}
+ int iO;
+};
+
+void g(O a, O b) {
+ int i = (a) ? 1+a : 0;
+ int j = (a&&b) ? a+b : i;
+ if (a) { }
+ printf("i = %d j = %d a.iO = %d b.iO = %d\n", i, j, a.iO, b.iO);
+}
+
+int main() {
+ int c = X(Z(y)); // OK: y.operator Z().operator X().operator int()
+ printf("c = %d\n", c);
+ float f = X(Z(y));
+ printf("f = %f\n", f);
+ int i = x;
+ printf("i = %d float = %f\n", i, float(x));
+ i = int(X(Z(y)));
+ f = float(X(Z(y)));
+ printf("i = %d float = %f\n", i,f);
+ f = (float)x;
+ i = (int)x;
+ printf("i = %d float = %f\n", i,f);
+
+ int d = (X)((Z)y);
+ printf("d = %d\n", d);
+
+ int e = (int)((X)((Z)y));
+ printf("e = %d\n", e);
+ O o1, o2;
+ g(o1, o2);
+}
+
+// Test. Conversion in base class is visible in derived class.
+class XB {
+ int a;
+public:
+ operator int();
+};
+
+class Yb : public XB {
+ double b;
+public:
+ operator char();
+};
+
+void f(Yb& a) {
+ int i = a; // OK. calls XB::operator int();
+ char ch = a; // OK. calls Yb::operator char();
+}
+
+struct A {
+ operator int() const;
+};
+
+// CHECK-LP64: .globl __ZN1ScviEv
+// CHECK-LP64-NEXT: __ZN1ScviEv:
+// CHECK-LP64: callq __ZN1Ycv1ZEv
+// CHECK-LP64: callq __ZN1Zcv1XEv
+// CHECK-LP64: callq __ZN1XcviEv
+// CHECK-LP64: callq __ZN1XcvfEv
+// CHECK-LP64: callq __ZN2XBcviEv
+// CHECK-LP64: callq __ZN2YbcvcEv
+
+// CHECK-LP32: .globl __ZN1ScviEv
+// CHECK-LP32-NEXT: __ZN1ScviEv:
+// CHECK-LP32: call L__ZN1Ycv1ZEv
+// CHECK-LP32: call L__ZN1Zcv1XEv
+// CHECK-LP32: call L__ZN1XcviEv
+// CHECK-LP32: call L__ZN1XcvfEv
+// CHECK-LP32: call L__ZN2XBcviEv
+// CHECK-LP32: call L__ZN2YbcvcEv
diff --git a/src/llvm-project/clang/test/CodeGenCXX/conversion-operator-base.cpp b/src/llvm-project/clang/test/CodeGenCXX/conversion-operator-base.cpp
new file mode 100644
index 0000000..e62e225
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/conversion-operator-base.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -emit-llvm-only %s -verify
+// expected-no-diagnostics
+// PR5730
+
+struct A { operator int(); float y; };
+struct B : A { double z; };
+void a() { switch(B()) {} }
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/convert-to-fptr.cpp b/src/llvm-project/clang/test/CodeGenCXX/convert-to-fptr.cpp
new file mode 100644
index 0000000..283493e
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/convert-to-fptr.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm %s -o - | \
+// RUN: FileCheck %s
+// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -emit-llvm %s -o - | \
+// RUN: FileCheck %s
+
+extern "C" int printf(...);
+
+int f1(int arg) { return arg; };
+
+int f2(float arg) { return int(arg); };
+
+typedef int (*fp1)(int);
+
+typedef int (*fp2)(float);
+
+struct A {
+ operator fp1() { return f1; }
+ operator fp2() { return f2; }
+} a;
+
+
+// Test for function reference.
+typedef int (&fr1)(int);
+typedef int (&fr2)(float);
+
+struct B {
+ operator fr1() { return f1; }
+ operator fr2() { return f2; }
+} b;
+
+int main()
+{
+ int i = a(10); // Calls f1 via pointer returned from conversion function
+ printf("i = %d\n", i);
+
+ int j = b(20); // Calls f1 via pointer returned from conversion function
+ printf("j = %d\n", j);
+ return 0;
+}
+
+// CHECK: call i32 (i32)* @_ZN1AcvPFiiEEv
+// CHECK: call i32 (i32)* @_ZN1BcvRFiiEEv
diff --git a/src/llvm-project/clang/test/CodeGenCXX/copy-assign-synthesis-1.cpp b/src/llvm-project/clang/test/CodeGenCXX/copy-assign-synthesis-1.cpp
new file mode 100644
index 0000000..5813d9c
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/copy-assign-synthesis-1.cpp
@@ -0,0 +1,95 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm %s -o - | \
+// RUN: FileCheck %s
+// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -emit-llvm %s -o - | \
+// RUN: FileCheck %s
+
+extern "C" int printf(...);
+
+struct B {
+ B() : B1(3.14), B2(3.15), auB2(3.16) {}
+ float B1;
+ float B2;
+ void pr() {
+ printf("B1 = %f B2 = %f auB1 = %f\n", B1, B2, auB1);
+ }
+
+ B& operator=(const B& arg) { B1 = arg.B1; B2 = arg.B2;
+ auB1 = arg.auB1; return *this; }
+ union {
+ float auB1;
+ float auB2;
+ };
+};
+
+struct M {
+ M() : M1(10), M2(11) , auM1(12) {}
+ int M1;
+ int M2;
+ void pr() {
+ printf("M1 = %d M2 = %d auM1 = %d auM2 = %d\n", M1, M2, auM1, auM2);
+ }
+ union {
+ int auM1;
+ int auM2;
+ };
+};
+
+struct N : B {
+ N() : N1(20), N2(21) {}
+ int N1;
+ int N2;
+ void pr() {
+ printf("N1 = %d N2 = %d\n", N1, N2);
+ for (unsigned i = 0; i < 3; i++)
+ for (unsigned j = 0; j < 2; j++)
+ printf("arr_b[%d][%d] = %f\n", i,j,arr_b[i][j].B1);
+ B::pr();
+ }
+ N& operator=(const N& arg) {
+ N1 = arg.N1; N2 = arg.N2;
+ for (unsigned i = 0; i < 3; i++)
+ for (unsigned j = 0; j < 2; j++)
+ arr_b[i][j] = arg.arr_b[i][j];
+ return *this;
+ }
+ B arr_b[3][2];
+};
+
+struct Q : B {
+ Q() : Q1(30), Q2(31) {}
+ int Q1;
+ int Q2;
+ void pr() {
+ printf("Q1 = %d Q2 = %d\n", Q1, Q2);
+ }
+};
+
+
+struct X : M , N {
+ X() : d(0.0), d1(1.1), d2(1.2), d3(1.3) {}
+ double d;
+ double d1;
+ double d2;
+ double d3;
+ void pr() {
+ printf("d = %f d1 = %f d2 = %f d3 = %f\n", d, d1,d2,d3);
+ M::pr(); N::pr();
+ q1.pr(); q2.pr();
+ }
+
+ Q q1, q2;
+};
+
+
+X srcX;
+X dstX;
+X dstY;
+
+int main() {
+ dstY = dstX = srcX;
+ srcX.pr();
+ dstX.pr();
+ dstY.pr();
+}
+
+// CHECK: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.X* @_ZN1XaSERKS_
diff --git a/src/llvm-project/clang/test/CodeGenCXX/copy-assign-synthesis-2.cpp b/src/llvm-project/clang/test/CodeGenCXX/copy-assign-synthesis-2.cpp
new file mode 100644
index 0000000..0bc7d3d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/copy-assign-synthesis-2.cpp
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s
+struct A {};
+A& (A::*x)(const A&) = &A::operator=;
+// CHECK-LABEL: define linkonce_odr {{.*}}%struct.A* @_ZN1AaSERKS_
diff --git a/src/llvm-project/clang/test/CodeGenCXX/copy-assign-synthesis-3.cpp b/src/llvm-project/clang/test/CodeGenCXX/copy-assign-synthesis-3.cpp
new file mode 100644
index 0000000..5469d11
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/copy-assign-synthesis-3.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -emit-llvm-only -verify %s
+// expected-no-diagnostics
+
+struct A {
+ A& operator=(A&);
+};
+
+struct B {
+ void operator=(B);
+};
+
+struct C {
+ A a;
+ B b;
+ float c;
+ int (A::*d)();
+ _Complex float e;
+ int f[10];
+ A g[2];
+ B h[2];
+};
+void a(C& x, C& y) {
+ x = y;
+}
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/copy-assign-synthesis.cpp b/src/llvm-project/clang/test/CodeGenCXX/copy-assign-synthesis.cpp
new file mode 100644
index 0000000..9c8ae88
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/copy-assign-synthesis.cpp
@@ -0,0 +1,79 @@
+// RUN: %clang_cc1 -emit-llvm -o %t %s
+// RUN: not grep "_ZN1XaSERK1X" %t
+
+extern "C" int printf(...);
+
+struct B {
+ B() : B1(3.14), B2(3.15), auB2(3.16) {}
+ float B1;
+ float B2;
+ void pr() {
+ printf("B1 = %f B2 = %f auB1 = %f\n", B1, B2, auB1);
+ }
+
+ union {
+ float auB1;
+ float auB2;
+ };
+};
+
+struct M {
+ M() : M1(10), M2(11) , auM1(12) {}
+ int M1;
+ int M2;
+ void pr() {
+ printf("M1 = %d M2 = %d auM1 = %d auM2 = %d\n", M1, M2, auM1, auM2);
+ }
+ union {
+ int auM1;
+ int auM2;
+ };
+};
+
+struct N : B {
+ N() : N1(20), N2(21) {}
+ int N1;
+ int N2;
+ void pr() {
+ printf("N1 = %d N2 = %d\n", N1, N2);
+ B::pr();
+ }
+};
+
+struct Q {
+ Q() : Q1(30), Q2(31) {}
+ int Q1;
+ int Q2;
+ void pr() {
+ printf("Q1 = %d Q2 = %d\n", Q1, Q2);
+ }
+};
+
+
+struct X : M , N {
+ X() : d(0.0), d1(1.1), d2(1.2), d3(1.3) {}
+ double d;
+ double d1;
+ double d2;
+ double d3;
+ void pr() {
+ printf("d = %f d1 = %f d2 = %f d3 = %f\n", d, d1,d2,d3);
+ M::pr(); N::pr();
+ q1.pr(); q2.pr();
+ }
+
+ Q q1, q2;
+};
+
+
+X srcX;
+X dstX;
+X dstY;
+
+int main() {
+ dstY = dstX = srcX;
+ srcX.pr();
+ dstX.pr();
+ dstY.pr();
+}
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/copy-assign-volatile-synthesis.cpp b/src/llvm-project/clang/test/CodeGenCXX/copy-assign-volatile-synthesis.cpp
new file mode 100644
index 0000000..eb13503
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/copy-assign-volatile-synthesis.cpp
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
+// rdar://9894548
+
+typedef unsigned long word_t;
+typedef unsigned long u64_t;
+typedef unsigned int u32_t;
+
+class ioapic_redir_t {
+public:
+ union {
+ struct {
+ word_t vector : 8;
+
+ word_t delivery_mode : 3;
+ word_t dest_mode : 1;
+
+ word_t delivery_status : 1;
+ word_t polarity : 1;
+ word_t irr : 1;
+ word_t trigger_mode : 1;
+
+ word_t mask : 1;
+ word_t _pad0 : 15;
+
+ word_t dest : 8;
+ };
+ volatile u32_t raw[2];
+ volatile u64_t raw64;
+ };
+};
+
+struct ioapic_shadow_struct
+{
+ ioapic_redir_t redirs[24];
+} ioapic_shadow[16];
+
+void init_ioapic(unsigned long ioapic_id)
+{
+ ioapic_redir_t entry;
+ ioapic_shadow[ioapic_id].redirs[3] = entry;
+}
+
+// CHECK: call void @llvm.memcpy
diff --git a/src/llvm-project/clang/test/CodeGenCXX/copy-constructor-elim-2.cpp b/src/llvm-project/clang/test/CodeGenCXX/copy-constructor-elim-2.cpp
new file mode 100644
index 0000000..26b6b48
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/copy-constructor-elim-2.cpp
@@ -0,0 +1,96 @@
+// RUN: %clang_cc1 -triple armv7-none-eabi -emit-llvm -o - %s | FileCheck %s
+
+struct A { int x; A(int); ~A(); };
+A f() { return A(0); }
+// CHECK-LABEL: define void @_Z1fv
+// CHECK: call {{.*}} @_ZN1AC1Ei
+// CHECK-NEXT: ret void
+
+// Verify that we do not elide copies when constructing a base class.
+namespace no_elide_base {
+ struct Base {
+ Base(const Base&);
+ ~Base();
+ };
+
+ struct Other {
+ operator Base() const;
+ };
+
+ struct Derived : public virtual Base {
+ Derived(const Other &O);
+ };
+
+ // CHECK: define {{.*}} @_ZN13no_elide_base7DerivedC1ERKNS_5OtherE(%"struct.no_elide_base::Derived"* returned %this, %"struct.no_elide_base::Other"* dereferenceable({{[0-9]+}}) %O) unnamed_addr
+ Derived::Derived(const Other &O)
+ // CHECK: call {{.*}} @_ZNK13no_elide_base5OthercvNS_4BaseEEv
+ // CHECK: call {{.*}} @_ZN13no_elide_base4BaseC2ERKS0_
+ // CHECK: call {{.*}} @_ZN13no_elide_base4BaseD1Ev
+ : Base(O)
+ {
+ // CHECK: ret
+ }
+}
+
+// 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 {{.*}} @_ZN6PR86831AC1ERKS0_
+ A a = (B().a);
+}
+
+}
+
+namespace PR12139 {
+ struct A {
+ A() : value(1) { }
+ A(A const &, int value = 2) : value(value) { }
+ int value;
+
+ static A makeA() { A a; a.value = 2; return a; }
+ };
+
+ // CHECK-LABEL: define i32 @_ZN7PR121394testEv
+ int test() {
+ // CHECK: call void @_ZN7PR121391A5makeAEv
+ // CHECK-NEXT: call %"struct.PR12139::A"* @_ZN7PR121391AC1ERKS0_i
+ A a(A::makeA(), 3);
+ // CHECK-NEXT: getelementptr inbounds
+ // CHECK-NEXT: load
+ // CHECK-NEXT: ret i32
+ return a.value;
+ }
+}
+
+namespace ElidableCallIsNotCopyCtor {
+ struct A { A(const A&); };
+ struct B : A {
+ B(B&);
+ B(A);
+ B(int);
+ };
+ void f() {
+ // Here, we construct via B(int) then B(A). The B(A) construction is
+ // elidable, but we don't have an AST representation for the case where we
+ // must elide not only a constructor call but also some argument
+ // conversions, so we don't elide it.
+ // CHECK-LABEL: define void @_ZN25ElidableCallIsNotCopyCtor1fEv(
+ // CHECK: call {{.*}} @_ZN25ElidableCallIsNotCopyCtor1BC1Ei(
+ // CHECK: call {{.*}} @_ZN25ElidableCallIsNotCopyCtor1AC1ERKS0_(
+ // CHECK: call {{.*}} @_ZN25ElidableCallIsNotCopyCtor1BC1ENS_1AE(
+ B b = 0;
+ }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/copy-constructor-elim.cpp b/src/llvm-project/clang/test/CodeGenCXX/copy-constructor-elim.cpp
new file mode 100644
index 0000000..7ba2310
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/copy-constructor-elim.cpp
@@ -0,0 +1,59 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple %ms_abi_triple -emit-llvm -o - %s | FileCheck %s -check-prefix MS
+// CHECK-NOT: _ZN1CC1ERK1C
+// CHECK-NOT: _ZN1SC1ERK1S
+// MS-NOT: ?0C@@QAE@ABV0
+// MS-NOT: ?0S@@QAE@ABV0
+
+extern "C" int printf(...);
+
+
+struct C {
+ C() : iC(6) {printf("C()\n"); }
+ C(const C& c) { printf("C(const C& c)\n"); }
+ int iC;
+};
+
+C foo() {
+ return C();
+};
+
+class X { // ...
+public:
+ X(int) {}
+ X(const X&, int i = 1, int j = 2, C c = foo()) {
+ printf("X(const X&, %d, %d, %d)\n", i, j, c.iC);
+ }
+};
+
+
+struct S {
+ S();
+};
+
+S::S() { printf("S()\n"); }
+
+void Call(S) {};
+
+int main() {
+ X a(1);
+ X b(a, 2);
+ X c = b;
+ X d(a, 5, 6);
+ S s;
+ Call(s);
+}
+
+struct V {
+ int x;
+};
+
+typedef V V_over_aligned __attribute((aligned(8)));
+extern const V_over_aligned gv1 = {};
+
+extern "C" V f() { return gv1; }
+
+// Make sure that we obey the destination's alignment requirements when emitting
+// the copy.
+// CHECK-LABEL: define {{.*}} @f(
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.{{i64|i32}}({{.*}}align 4{{.*}}, i8* align 8 bitcast (%struct.V* @gv1 to i8*), {{i64|i32}} 4, i1 false)
diff --git a/src/llvm-project/clang/test/CodeGenCXX/copy-constructor-synthesis-2.cpp b/src/llvm-project/clang/test/CodeGenCXX/copy-constructor-synthesis-2.cpp
new file mode 100644
index 0000000..7940101c0
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/copy-constructor-synthesis-2.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++11 -emit-llvm -o - %s | FileCheck %s
+
+union PR23373 {
+ PR23373(PR23373&) = default;
+ PR23373 &operator=(PR23373&) = default;
+ int n;
+ float f;
+};
+extern PR23373 pr23373_a;
+
+PR23373 pr23373_b(pr23373_a);
+// CHECK-LABEL: define {{.*}} @__cxx_global_var_init(
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.{{i32|i64}}({{.*}}align 4{{.*}}@pr23373_b{{.*}}, {{.*}}align 4{{.*}} @pr23373_a{{.*}}, [[W:i32|i64]] 4, i1 false)
+
+PR23373 pr23373_f() { return pr23373_a; }
+// CHECK-LABEL: define {{.*}} @_Z9pr23373_fv(
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.[[W]]({{.*}}align 4{{.*}}align 4{{.*}}, [[W]] 4, i1 false)
+
+void pr23373_g(PR23373 &a, PR23373 &b) { a = b; }
+// CHECK-LABEL: define {{.*}} @_Z9pr23373_g
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.[[W]]({{.*}}align 4{{.*}}align 4{{.*}}, [[W]] 4, i1 false)
+
+struct A { virtual void a(); };
+A x(A& y) { return y; }
+
+// CHECK: define linkonce_odr {{.*}} @_ZN1AC1ERKS_(%struct.A* {{.*}}%this, %struct.A* dereferenceable({{[0-9]+}})) unnamed_addr
+// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTV1A, i32 0, inrange i32 0, i32 2) to i32 (...)**)
diff --git a/src/llvm-project/clang/test/CodeGenCXX/copy-constructor-synthesis.cpp b/src/llvm-project/clang/test/CodeGenCXX/copy-constructor-synthesis.cpp
new file mode 100644
index 0000000..4fdd8a3
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/copy-constructor-synthesis.cpp
@@ -0,0 +1,193 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - %s | FileCheck %s
+
+extern "C" int printf(...);
+
+int init = 100;
+
+struct M {
+ int iM;
+ M() : iM(init++) {}
+};
+
+struct N {
+ int iN;
+ N() : iN(200) {}
+ N(N const & arg){this->iN = arg.iN; }
+};
+
+struct P {
+ int iP;
+ P() : iP(init++) {}
+};
+
+
+// CHECK-LABEL: define linkonce_odr void @_ZN1XC1ERKS_(%struct.X* %this, %struct.X* dereferenceable({{[0-9]+}})) 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") {}
+ P p0;
+ void pr() {
+ printf("iM = %d iN = %d, m1.iM = %d\n", iM, iN, m1.iM);
+ printf("im = %d p0.iP = %d, p1.iP = %d\n", iP, p0.iP, p1.iP);
+ printf("f1 = %f d1 = %f i1 = %d name(%s) \n", f1, d1, i1, name);
+ printf("bf1 = %x bf2 = %x\n", bf1, bf2);
+ printf("au_i2 = %d\n", au_i2);
+ printf("au1_1 = %s\n", au1_1);
+ }
+ M m1;
+ P p1;
+ float f1;
+ double d1;
+ int i1;
+ const char *name;
+ unsigned bf1 : 8;
+ unsigned bf2 : 16;
+ int arr[2];
+ _Complex float complex;
+
+ union {
+ int au_i1;
+ int au_i2;
+ };
+ union {
+ const char * au1_1;
+ float au1_2;
+ int au1_3;
+ const char * au1_4;
+ };
+};
+
+static int ix = 1;
+// class with user-defined copy constructor.
+struct S {
+ S() : iS(ix++) { }
+ S(const S& arg) { *this = arg; }
+ int iS;
+};
+
+// class with trivial copy constructor.
+struct I {
+ I() : iI(ix++) { }
+ int iI;
+};
+
+struct XM {
+ XM() { }
+ double dXM;
+ S ARR_S[3][4][2];
+ void pr() {
+ for (unsigned i = 0; i < 3; i++)
+ for (unsigned j = 0; j < 4; j++)
+ for (unsigned k = 0; k < 2; k++)
+ printf("ARR_S[%d][%d][%d] = %d\n", i,j,k, ARR_S[i][j][k].iS);
+ for (unsigned i = 0; i < 3; i++)
+ for (unsigned k = 0; k < 2; k++)
+ printf("ARR_I[%d][%d] = %d\n", i,k, ARR_I[i][k].iI);
+ }
+ I ARR_I[3][2];
+};
+
+int main() {
+ X a;
+ X b(a);
+ b.pr();
+ X x;
+ X c(x);
+ c.pr();
+
+ XM m0;
+ XM m1 = m0;
+ m1.pr();
+}
+
+struct A {
+};
+
+struct B : A {
+ A &a;
+};
+
+void f(const B &b1) {
+ B b2(b1);
+}
+
+// PR6628
+namespace PR6628 {
+
+struct T {
+ T();
+ ~T();
+
+ double d;
+};
+
+struct A {
+ A(const A &other, const T &t = T(), const T& t2 = T());
+};
+
+struct B : A {
+ A a1;
+ A a2;
+ A a[10];
+};
+
+// Force the copy constructor to be synthesized.
+void f(B b1) {
+ B b2 = b1;
+}
+
+// CHECK: define linkonce_odr dereferenceable({{[0-9]+}}) [[A:%.*]]* @_ZN12rdar138169401AaSERKS0_(
+// CHECK: [[THIS:%.*]] = load [[A]]*, [[A]]**
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[A]], [[A]]* [[THIS]], i32 0, i32 1
+// CHECK-NEXT: [[OTHER:%.*]] = load [[A]]*, [[A]]**
+// CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[A]], [[A]]* [[OTHER]], i32 0, i32 1
+// CHECK-NEXT: [[T4:%.*]] = bitcast i16* [[T0]] to i8*
+// CHECK-NEXT: [[T5:%.*]] = bitcast i16* [[T2]] to i8*
+// CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[T4]], i8* align 8 [[T5]], i64 8, i1 false)
+// CHECK-NEXT: ret [[A]]* [[THIS]]
+
+// CHECK-LABEL: define linkonce_odr void @_ZN6PR66281BC2ERKS0_(%"struct.PR6628::B"* %this, %"struct.PR6628::B"* dereferenceable({{[0-9]+}})) unnamed_addr
+// CHECK: call void @_ZN6PR66281TC1Ev
+// CHECK: call void @_ZN6PR66281TC1Ev
+// CHECK: call void @_ZN6PR66281AC2ERKS0_RKNS_1TES5_
+// CHECK: call void @_ZN6PR66281TD1Ev
+// CHECK: call void @_ZN6PR66281TD1Ev
+// CHECK: call void @_ZN6PR66281TC1Ev
+// CHECK: call void @_ZN6PR66281TC1Ev
+// CHECK: call void @_ZN6PR66281AC1ERKS0_RKNS_1TES5_
+// CHECK: call void @_ZN6PR66281TD1Ev
+// CHECK: call void @_ZN6PR66281TD1Ev
+// CHECK: call void @_ZN6PR66281TC1Ev
+// CHECK: call void @_ZN6PR66281TC1Ev
+// CHECK: call void @_ZN6PR66281AC1ERKS0_RKNS_1TES5_
+// CHECK: call void @_ZN6PR66281TD1Ev
+// CHECK: call void @_ZN6PR66281TD1Ev
+
+// CHECK-LABEL: define linkonce_odr void @_ZN12rdar138169401AC2ERKS0_(
+// CHECK: [[THIS:%.*]] = load [[A]]*, [[A]]**
+// CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[THIS]] to i32 (...)***
+// CHECK-NEXT: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [4 x i8*] }, { [4 x i8*] }* @_ZTVN12rdar138169401AE, i32 0, inrange i32 0, i32 2) to i32 (...)**), i32 (...)*** [[T0]]
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[A]], [[A]]* [[THIS]], i32 0, i32 1
+// CHECK-NEXT: [[OTHER:%.*]] = load [[A]]*, [[A]]**
+// CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[A]], [[A]]* [[OTHER]], i32 0, i32 1
+// CHECK-NEXT: [[T4:%.*]] = bitcast i16* [[T0]] to i8*
+// CHECK-NEXT: [[T5:%.*]] = bitcast i16* [[T2]] to i8*
+// CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[T4]], i8* align 8 [[T5]], i64 8, i1 false)
+// CHECK-NEXT: ret void
+}
+
+// rdar://13816940
+// Test above because things get weirdly re-ordered.
+namespace rdar13816940 {
+ struct A {
+ virtual ~A();
+ unsigned short a : 1;
+ unsigned short : 15;
+ unsigned other;
+ };
+
+ void test(A &a) {
+ A x = a; // force copy constructor into existence
+ x = a; // also force the copy assignment operator
+ }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/copy-in-cplus-object.cpp b/src/llvm-project/clang/test/CodeGenCXX/copy-in-cplus-object.cpp
new file mode 100644
index 0000000..bdfca5e
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/copy-in-cplus-object.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 %s -fblocks -triple x86_64-apple-darwin -emit-llvm -o - | FileCheck %s
+
+struct S {
+ S(const char *);
+ ~S();
+};
+
+struct TestObject
+{
+ TestObject(const TestObject& inObj, int def = 100, const S &Silly = "silly");
+ TestObject();
+ ~TestObject();
+ TestObject& operator=(const TestObject& inObj);
+ int version() const;
+
+};
+
+void testRoutine() {
+ TestObject one;
+ int (^V)() = ^{ return one.version(); };
+}
+
+// CHECK: call void @_ZN10TestObjectC1Ev
+// CHECK: call void @_ZN1SC1EPKc
+// CHECK: call void @_ZN10TestObjectC1ERKS_iRK1S
+// CHECK: call void @_ZN1SD1Ev
+// CHECK: call void @_ZN10TestObjectD1Ev
+// CHECK: call void @_ZN10TestObjectD1Ev
diff --git a/src/llvm-project/clang/test/CodeGenCXX/copy-initialization.cpp b/src/llvm-project/clang/test/CodeGenCXX/copy-initialization.cpp
new file mode 100644
index 0000000..1a16013
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/copy-initialization.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
+
+struct Foo {
+ Foo();
+ Foo(const Foo&);
+};
+
+struct Bar {
+ Bar();
+ operator const Foo&() const;
+};
+
+void f(Foo);
+
+// CHECK-LABEL: define void @_Z1g3Foo(%struct.Foo* %foo)
+void g(Foo foo) {
+ // CHECK: call void @_ZN3BarC1Ev
+ // CHECK: @_ZNK3BarcvRK3FooEv
+ // CHECK: call void @_Z1f3Foo
+ f(Bar());
+ // CHECK: call void @_ZN3FooC1Ev
+ // CHECK: call void @_Z1f3Foo
+ f(Foo());
+ // CHECK: call void @_ZN3FooC1ERKS_
+ // CHECK: call void @_Z1f3Foo
+ f(foo);
+ // CHECK: ret
+}
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/coverage.cpp b/src/llvm-project/clang/test/CodeGenCXX/coverage.cpp
new file mode 100644
index 0000000..4b23324
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/coverage.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s -triple %itanium_abi_triple -emit-llvm -o - -test-coverage -femit-coverage-notes | FileCheck %s
+
+extern "C" void test_name1() {}
+void test_name2() {}
+
+// CHECK: !DISubprogram(name: "test_name1",
+// CHECK-NOT: linkageName:
+// CHECK-SAME: ){{$}}
+// CHECK: !DISubprogram(name: "test_name2", linkageName: "_Z10test_name2v"
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cp-blocks-linetables.cpp b/src/llvm-project/clang/test/CodeGenCXX/cp-blocks-linetables.cpp
new file mode 100644
index 0000000..46ab16e
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cp-blocks-linetables.cpp
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 -fblocks -debug-info-kind=limited -emit-llvm %s -o - | FileCheck %s
+// Ensure that we generate a line table entry for the block cleanup.
+// CHECK: define {{.*}} @__main_block_invoke
+// CHECK: _NSConcreteStackBlock
+// CHECK: = bitcast {{.*}}, !dbg ![[L1:[0-9]+]]
+// CHECK-NOT: call {{.*}} @_Block_object_dispose{{.*}}, !dbg ![[L1]]
+// CHECK: ret
+
+void * _NSConcreteStackBlock;
+#ifdef __cplusplus
+extern "C" void exit(int);
+#else
+extern void exit(int);
+#endif
+
+enum numbers {
+ zero, one, two, three, four
+};
+
+typedef enum numbers (^myblock)(enum numbers);
+
+
+double test(myblock I) {
+ return I(three);
+}
+
+int main() {
+ __block enum numbers x = one;
+ __block enum numbers y = two;
+
+ /* Breakpoint for first Block function. */
+ myblock CL = ^(enum numbers z)
+ { enum numbers savex = x;
+ { __block enum numbers x = savex;
+ y = z;
+ if (y != three)
+ exit (6);
+ test (
+ /* Breakpoint for second Block function. */
+ ^ (enum numbers z) {
+ if (y != three) {
+ exit(1);
+ }
+ if (x != one)
+ exit(2);
+ x = z;
+ if (x != three)
+ exit(3);
+ if (y != three)
+ exit(4);
+ return (enum numbers) four;
+ });}
+ return x;
+ };
+
+ enum numbers res = (enum numbers)test(CL);
+
+ if (res != one)
+ exit (5);
+ return 0;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/crash.cpp b/src/llvm-project/clang/test/CodeGenCXX/crash.cpp
new file mode 100644
index 0000000..63bca48
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/crash.cpp
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 %s -std=c++11 -emit-llvm-only
+// RUN: %clang_cc1 -emit-obj -o %t -debug-info-kind=line-tables-only -std=c++11 %s
+// RUN: %clang_cc1 -emit-obj -o %t -debug-info-kind=line-directives-only -std=c++11 %s
+// CHECK that we don't crash.
+
+// PR11676's example is ill-formed:
+/*
+union _XEvent {
+};
+void ProcessEvent() {
+ _XEvent pluginEvent = _XEvent();
+}
+*/
+
+// Example from PR11665:
+void f() {
+ union U { int field; } u = U();
+ (void)U().field;
+}
+
+namespace PR17476 {
+struct string {
+ string(const char *__s);
+ string &operator+=(const string &__str);
+};
+
+template <class ELFT> void finalizeDefaultAtomValues() {
+ auto startEnd = [&](const char * sym)->void {
+ string start("__");
+ start += sym;
+ }
+ ;
+ startEnd("preinit_array");
+}
+
+void f() { finalizeDefaultAtomValues<int>(); }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/ctor-dtor-alias.cpp b/src/llvm-project/clang/test/CodeGenCXX/ctor-dtor-alias.cpp
new file mode 100644
index 0000000..89244cc
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/ctor-dtor-alias.cpp
@@ -0,0 +1,248 @@
+// RUN: %clang_cc1 %s -triple i686-linux -emit-llvm -o - -mconstructor-aliases | FileCheck --check-prefix=NOOPT %s
+
+// RUN: %clang_cc1 %s -triple i686-linux -emit-llvm -o - -mconstructor-aliases -O1 -disable-llvm-passes > %t
+// RUN: FileCheck --check-prefix=CHECK1 --input-file=%t %s
+// RUN: FileCheck --check-prefix=CHECK2 --input-file=%t %s
+// RUN: FileCheck --check-prefix=CHECK3 --input-file=%t %s
+// RUN: FileCheck --check-prefix=CHECK4 --input-file=%t %s
+// RUN: FileCheck --check-prefix=CHECK5 --input-file=%t %s
+// RUN: FileCheck --check-prefix=CHECK6 --input-file=%t %s
+
+// RUN: %clang_cc1 %s -triple i686-pc-windows-gnu -emit-llvm -o - -mconstructor-aliases -O1 -disable-llvm-passes | FileCheck --check-prefix=COFF %s
+
+namespace test1 {
+// Test that we produce the appropriate comdats when creating aliases to
+// weak_odr constructors and destructors.
+
+// CHECK1: @_ZN5test16foobarIvEC1Ev = weak_odr unnamed_addr alias void {{.*}} @_ZN5test16foobarIvEC2Ev
+// CHECK1: @_ZN5test16foobarIvED1Ev = weak_odr unnamed_addr alias void (%"struct.test1::foobar"*), void (%"struct.test1::foobar"*)* @_ZN5test16foobarIvED2Ev
+// CHECK1: define weak_odr void @_ZN5test16foobarIvEC2Ev({{.*}} comdat($_ZN5test16foobarIvEC5Ev)
+// CHECK1: define weak_odr void @_ZN5test16foobarIvED2Ev({{.*}} comdat($_ZN5test16foobarIvED5Ev)
+// CHECK1: define weak_odr void @_ZN5test16foobarIvED0Ev({{.*}} comdat($_ZN5test16foobarIvED5Ev)
+// CHECK1-NOT: comdat
+
+// COFF doesn't support comdats with arbitrary names (C5/D5).
+// COFF: define weak_odr {{.*}} void @_ZN5test16foobarIvEC2Ev({{.*}} comdat align
+// COFF: define weak_odr {{.*}} void @_ZN5test16foobarIvEC1Ev({{.*}} comdat align
+// COFF: define weak_odr {{.*}} void @_ZN5test16foobarIvED2Ev({{.*}} comdat align
+// COFF: define weak_odr {{.*}} void @_ZN5test16foobarIvED0Ev({{.*}} comdat align
+
+template <typename T>
+struct foobar {
+ foobar() {}
+ virtual ~foobar() {}
+};
+
+template struct foobar<void>;
+}
+
+namespace test2 {
+// test that when the destrucor is linkonce_odr we just replace every use of
+// C1 with C2.
+
+// CHECK1: define internal void @__cxx_global_var_init()
+// CHECK1: call void @_ZN5test26foobarIvEC2Ev
+// CHECK1: define linkonce_odr void @_ZN5test26foobarIvEC2Ev({{.*}} comdat align
+void g();
+template <typename T> struct foobar {
+ foobar() { g(); }
+};
+foobar<void> x;
+}
+
+namespace test3 {
+// test that instead of an internal alias we just use the other destructor
+// directly.
+
+// CHECK1: define internal void @__cxx_global_var_init.1()
+// CHECK1: call i32 @__cxa_atexit{{.*}}_ZN5test312_GLOBAL__N_11AD2Ev
+// CHECK1: define internal void @_ZN5test312_GLOBAL__N_11AD2Ev(
+namespace {
+struct A {
+ ~A() {}
+};
+
+struct B : public A {};
+}
+
+B x;
+}
+
+namespace test4 {
+ // Test that we don't produce aliases from B to A. We cannot because we cannot
+ // guarantee that they will be present in every TU. Instead, we just call
+ // A's destructor directly.
+
+ // CHECK1: define internal void @__cxx_global_var_init.2()
+ // CHECK1: call i32 @__cxa_atexit{{.*}}_ZN5test41AD2Ev
+ // CHECK1: define linkonce_odr void @_ZN5test41AD2Ev({{.*}} comdat align
+
+ // test that we don't do this optimization at -O0 so that the debugger can
+ // see both destructors.
+ // NOOPT: define internal void @__cxx_global_var_init.2()
+ // NOOPT: call i32 @__cxa_atexit{{.*}}@_ZN5test41BD2Ev
+ // NOOPT: define linkonce_odr void @_ZN5test41BD2Ev({{.*}} comdat align
+ struct A {
+ virtual ~A() {}
+ };
+ struct B : public A{
+ ~B() {}
+ };
+ B X;
+}
+
+namespace test5 {
+ // similar to test4, but with an internal B.
+
+ // CHECK2: define internal void @__cxx_global_var_init.3()
+ // CHECK2: call i32 @__cxa_atexit{{.*}}_ZN5test51AD2Ev
+ // CHECK2: define linkonce_odr void @_ZN5test51AD2Ev({{.*}} comdat align
+ struct A {
+ virtual ~A() {}
+ };
+ namespace {
+ struct B : public A{
+ ~B() {}
+ };
+ }
+ B X;
+}
+
+namespace test6 {
+ // Test that we use ~A directly, even when ~A is not defined. The symbol for
+ // ~B would have been internal and still contain a reference to ~A.
+ struct A {
+ virtual ~A();
+ };
+ namespace {
+ struct B : public A {
+ ~B() {}
+ };
+ }
+ B X;
+ // CHECK3: define internal void @__cxx_global_var_init.4()
+ // CHECK3: call i32 @__cxa_atexit({{.*}}@_ZN5test61AD2Ev
+}
+
+namespace test7 {
+ // Test that we don't produce an alias from ~B to ~A<int> (or crash figuring
+ // out if we should).
+ // pr17875.
+ // CHECK3: define void @_ZN5test71BD2Ev
+ template <typename> struct A {
+ ~A() {}
+ };
+ class B : A<int> {
+ ~B();
+ };
+ template class A<int>;
+ B::~B() {}
+}
+
+namespace test8 {
+ // Test that we replace ~zed with ~bar which is an alias to ~foo.
+ // CHECK4: @_ZN5test83barD2Ev = unnamed_addr alias {{.*}} @_ZN5test83fooD2Ev
+ // CHECK4: define internal void @__cxx_global_var_init.5()
+ // CHECK4: call i32 @__cxa_atexit({{.*}}@_ZN5test83barD2Ev
+ struct foo {
+ ~foo();
+ };
+ foo::~foo() {}
+ struct bar : public foo {
+ ~bar();
+ };
+ bar::~bar() {}
+ struct zed : public bar {};
+ zed foo;
+}
+
+namespace test9 {
+struct foo {
+ __attribute__((stdcall)) ~foo() {
+ }
+};
+
+struct bar : public foo {};
+
+void zed() {
+ // Test that we produce a call to bar's destructor. We used to call foo's, but
+ // it has a different calling conversion.
+ // CHECK4: call void @_ZN5test93barD2Ev
+ bar ptr;
+}
+}
+
+// CHECK5: @_ZTV1C = linkonce_odr unnamed_addr constant { [4 x i8*] } {{[^@]*}}@_ZTI1C {{[^@]*}}@_ZN1CD2Ev {{[^@]*}}@_ZN1CD0Ev {{[^@]*}}]
+// r194296 replaced C::~C with B::~B without emitting the later.
+
+class A {
+public:
+ A(int);
+ virtual ~A();
+};
+
+template <class>
+class B : A {
+public:
+ B()
+ : A(0) {
+ }
+ __attribute__((always_inline)) ~B() {
+ }
+};
+
+extern template class B<char>;
+
+class C : B<char> {
+};
+
+void
+fn1() {
+ new C;
+}
+
+namespace test10 {
+// Test that if a destructor is in a comdat, we don't try to emit is as an
+// alias to a base class destructor.
+struct bar {
+ ~bar();
+};
+bar::~bar() {
+}
+} // closing the namespace causes ~bar to be sent to CodeGen
+namespace test10 {
+template <typename T>
+struct foo : public bar {
+ ~foo();
+};
+template <typename T>
+foo<T>::~foo() {}
+template class foo<int>;
+// CHECK5: define weak_odr void @_ZN6test103fooIiED2Ev({{.*}} comdat($_ZN6test103fooIiED5Ev)
+}
+
+namespace test11 {
+// Test that when we don't have to worry about COMDATs we produce an alias
+// from complate to base and from base to base class base.
+struct bar {
+ ~bar();
+};
+bar::~bar() {}
+struct foo : public bar {
+ ~foo();
+};
+foo::~foo() {}
+// CHECK6: @_ZN6test113fooD2Ev = unnamed_addr alias {{.*}} @_ZN6test113barD2Ev
+// CHECK6: @_ZN6test113fooD1Ev = unnamed_addr alias {{.*}} @_ZN6test113fooD2Ev
+}
+
+namespace test12 {
+template <int>
+struct foo {
+ ~foo() { delete this; }
+};
+
+template class foo<1>;
+// CHECK6: @_ZN6test123fooILi1EED1Ev = weak_odr unnamed_addr alias {{.*}} @_ZN6test123fooILi1EED2Ev
+// CHECK6: define weak_odr void @_ZN6test123fooILi1EED2Ev({{.*}}) {{.*}} comdat($_ZN6test123fooILi1EED5Ev)
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/ctor-globalopt.cpp b/src/llvm-project/clang/test/CodeGenCXX/ctor-globalopt.cpp
new file mode 100644
index 0000000..0951278
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/ctor-globalopt.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - %s -O2 | opt - -S -globalopt -o - | FileCheck %s --check-prefix=O1
+// RUN: %clang_cc1 -triple %ms_abi_triple -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple %ms_abi_triple -emit-llvm -o - %s -O2 | opt - -S -globalopt -o - | FileCheck %s --check-prefix=O1
+
+// Check that GlobalOpt can eliminate static constructors for simple implicit
+// constructors. This is a targeted integration test to make sure that LLVM's
+// optimizers are able to process Clang's IR. GlobalOpt in particular is
+// sensitive to the casts we emit.
+
+// CHECK: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }]
+// CHECK: [{ i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_ctor_globalopt.cpp, i8* null }]
+
+// CHECK-LABEL: define internal {{.*}}void @_GLOBAL__sub_I_ctor_globalopt.cpp()
+// CHECK: call {{.*}}void @
+// CHECK-NOT: call{{ }}
+
+// O1: @llvm.global_ctors = appending global [0 x { i32, void ()*, i8* }] zeroinitializer
+
+struct A {
+ virtual void f();
+ int a;
+};
+struct B : virtual A {
+ virtual void g();
+ int b;
+};
+B b;
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx-apple-kext.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx-apple-kext.cpp
new file mode 100644
index 0000000..e5ec78b
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cxx-apple-kext.cpp
@@ -0,0 +1,36 @@
+// RUN: %clangxx -target x86_64-apple-darwin10 %s -flto -S -o - |\
+// RUN: FileCheck --check-prefix=CHECK-NO-KEXT %s
+// RUN: %clangxx -target x86_64-apple-darwin10 %s -fapple-kext -flto -S -o - |\
+// RUN: FileCheck --check-prefix=CHECK-KEXT %s
+
+// CHECK-NO-KEXT-NOT: _GLOBAL__D_a
+// CHECK-NO-KEXT: @is_hosted = global
+// CHECK-NO-KEXT: @_ZTI3foo = {{.*}} @_ZTVN10__cxxabiv117
+// CHECK-NO-KEXT: call i32 @__cxa_atexit({{.*}} @_ZN3fooD1Ev
+// CHECK-NO-KEXT: declare i32 @__cxa_atexit
+
+// CHECK-KEXT: @_ZTV3foo =
+// CHECK-KEXT-NOT: @_ZTVN10__cxxabiv117
+// CHECK-KEXT-NOT: call i32 @__cxa_atexit({{.*}} @_ZN3fooD1Ev
+// CHECK-KEXT-NOT: declare i32 @__cxa_atexit
+// CHECK-KEXT: @is_freestanding = global
+// CHECK-KEXT: _GLOBAL__D_a
+// CHECK-KEXT: call void @_ZN3fooD1Ev(%class.foo* @a)
+
+class foo {
+public:
+ foo();
+ virtual ~foo();
+};
+
+foo a;
+foo::~foo() {}
+
+#if !(__STDC_HOSTED__ == 1)
+int is_freestanding = 1;
+#else
+int is_hosted = 1;
+#endif
+
+extern "C" void f1() {
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx-block-objects.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx-block-objects.cpp
new file mode 100644
index 0000000..d28bcb6
--- /dev/null
+++ b/src/llvm-project/clang/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-LABEL: define linkonce_odr hidden void @__copy_helper_block_
+// CHECK: call void @_ZN1AC1ERKS_
+
+
+// CHECK-LABEL:define linkonce_odr hidden void @__destroy_helper_block_
+// CHECK: call void @_ZN1AD1Ev
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx0x-defaulted-templates.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx0x-defaulted-templates.cpp
new file mode 100644
index 0000000..6f4c533
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cxx0x-defaulted-templates.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
+
+template <typename T>
+struct X {
+ X();
+};
+
+// CHECK: define {{.*}} @_ZN1XIbEC2Ev
+// CHECK: define {{.*}} @_ZN1XIbEC1Ev
+template <> X<bool>::X() = default;
+
+// CHECK: define weak_odr {{.*}} @_ZN1XIiEC2Ev
+// CHECK: define weak_odr {{.*}} @_ZN1XIiEC1Ev
+template <typename T> X<T>::X() = default;
+template X<int>::X();
+
+// CHECK: define linkonce_odr {{.*}} @_ZN1XIcEC1Ev
+// CHECK: define linkonce_odr {{.*}} @_ZN1XIcEC2Ev
+X<char> x;
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx0x-delegating-ctors.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx0x-delegating-ctors.cpp
new file mode 100644
index 0000000..614983d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cxx0x-delegating-ctors.cpp
@@ -0,0 +1,103 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -fexceptions -fcxx-exceptions -std=c++11 -o - %s | FileCheck %s
+
+struct non_trivial {
+ non_trivial();
+ ~non_trivial() noexcept(false);
+};
+non_trivial::non_trivial() {}
+non_trivial::~non_trivial() noexcept(false) {}
+
+// We use a virtual base to ensure that the constructor
+// delegation optimization (complete->base) can't be
+// performed.
+struct delegator {
+ non_trivial n;
+ delegator();
+ delegator(int);
+ delegator(char);
+ delegator(bool);
+};
+
+delegator::delegator() {
+ throw 0;
+}
+
+
+delegator::delegator(bool)
+{}
+
+// CHECK-LABEL: define {{.*}} @_ZN9delegatorC2Ec
+// CHECK: {{.*}} @_ZN9delegatorC2Eb
+// CHECK: void @__cxa_throw
+// CHECK: void @__clang_call_terminate
+// CHECK: {{.*}} @_ZN9delegatorD2Ev
+
+// CHECK-LABEL: define {{.*}} @_ZN9delegatorC1Ec
+// CHECK: {{.*}} @_ZN9delegatorC1Eb
+// CHECK: void @__cxa_throw
+// CHECK: void @__clang_call_terminate
+// CHECK: {{.*}} @_ZN9delegatorD1Ev
+delegator::delegator(char)
+ : delegator(true) {
+ throw 0;
+}
+
+// CHECK-LABEL: define {{.*}} @_ZN9delegatorC2Ei
+// CHECK: {{.*}} @_ZN9delegatorC2Ev
+// CHECK-NOT: void @_ZSt9terminatev
+// CHECK: ret
+// CHECK-NOT: void @_ZSt9terminatev
+
+// CHECK-LABEL: define {{.*}} @_ZN9delegatorC1Ei
+// CHECK: {{.*}} @_ZN9delegatorC1Ev
+// CHECK-NOT: void @_ZSt9terminatev
+// CHECK: ret
+// CHECK-NOT: void @_ZSt9terminatev
+delegator::delegator(int)
+ : delegator()
+{}
+
+namespace PR12890 {
+ class X {
+ int x;
+ X() = default;
+ X(int);
+ };
+ X::X(int) : X() {}
+}
+// CHECK: define {{.*}} @_ZN7PR128901XC1Ei(%"class.PR12890::X"* %this, i32)
+// CHECK: call void @llvm.memset.p0i8.{{i32|i64}}(i8* align 4 {{.*}}, i8 0, {{i32|i64}} 4, i1 false)
+
+namespace PR14588 {
+ void other();
+
+ class Base {
+ public:
+ Base() { squawk(); }
+ virtual ~Base() {}
+
+ virtual void squawk() { other(); }
+ };
+
+
+ class Foo : public virtual Base {
+ public:
+ Foo();
+ Foo(const void * inVoid);
+ virtual ~Foo() {}
+
+ virtual void squawk() { other(); }
+ };
+
+ // CHECK-LABEL: define void @_ZN7PR145883FooC1Ev(%"class.PR14588::Foo"*
+ // CHECK: call void @_ZN7PR145883FooC1EPKv(
+ // CHECK: invoke void @_ZN7PR145885otherEv()
+ // CHECK: call void @_ZN7PR145883FooD1Ev
+ // CHECK: resume
+
+ Foo::Foo() : Foo(__null) { other(); }
+ Foo::Foo(const void *inVoid) {
+ squawk();
+ }
+
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx0x-initializer-array.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx0x-initializer-array.cpp
new file mode 100644
index 0000000..4a7e452
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cxx0x-initializer-array.cpp
@@ -0,0 +1,112 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -std=c++11 -S -emit-llvm -o - %s -Wno-address-of-temporary | FileCheck %s
+
+// CHECK: @[[THREE_NULL_MEMPTRS:.*]] = private constant [3 x i32] [i32 -1, i32 -1, i32 -1]
+
+struct A { int a[1]; };
+typedef A x[];
+int f() {
+ x{{{1}}};
+ // CHECK-LABEL: define i32 @_Z1fv
+ // CHECK: store i32 1
+ // (It's okay if the output changes here, as long as we don't crash.)
+ return 0;
+}
+
+namespace ValueInitArrayOfMemPtr {
+ struct S {};
+ typedef int (S::*p);
+ typedef p a[3];
+ void f(const a &);
+
+ struct Agg1 {
+ int n;
+ p x;
+ };
+
+ struct Agg2 {
+ int n;
+ a x;
+ };
+
+ struct S1 {
+ p x;
+ S1();
+ };
+
+ // CHECK-LABEL: define void @_ZN22ValueInitArrayOfMemPtr1fEi
+ void f(int n) {
+ Agg1 a = { n };
+ // CHECK: store i32 -1,
+
+ Agg2 b = { n };
+ // CHECK: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %{{.*}}, i8* align 4 bitcast ([3 x i32]* @[[THREE_NULL_MEMPTRS]] to i8*), i32 12, i1 false)
+ }
+
+ // Test dynamic initialization.
+ // CHECK-LABEL: define void @_ZN22ValueInitArrayOfMemPtr1gEMNS_1SEi
+ void g(p ptr) {
+ // CHECK: store i32 -1,
+ f(a{ptr});
+ }
+}
+
+namespace array_dtor {
+ struct S { S(); ~S(); };
+ using T = S[3];
+ void f(const T &);
+ void f(T *);
+ // CHECK-LABEL: define void @_ZN10array_dtor1gEv(
+ void g() {
+ // CHECK: %[[ARRAY:.*]] = alloca [3 x
+ // CHECK: br
+
+ // Construct loop.
+ // CHECK: call void @_ZN10array_dtor1SC1Ev(
+ // CHECK: br i1
+
+ // CHECK: call void @_ZN10array_dtor1fERA3_KNS_1SE(
+ // CHECK: br
+
+ // Destruct loop.
+ // CHECK: call void @_ZN10array_dtor1SD1Ev(
+ // CHECK: br i1
+ f(T{});
+
+ // CHECK: ret void
+ }
+ // CHECK-LABEL: define void @_ZN10array_dtor1hEv(
+ void h() {
+ // CHECK: %[[ARRAY:.*]] = alloca [3 x
+ // CHECK: br
+
+ // CHECK: call void @_ZN10array_dtor1SC1Ev(
+ // CHECK: br i1
+ T &&t = T{};
+
+ // CHECK: call void @_ZN10array_dtor1fERA3_KNS_1SE(
+ // CHECK: br
+ f(t);
+
+ // CHECK: call void @_ZN10array_dtor1SD1Ev(
+ // CHECK: br i1
+
+ // CHECK: ret void
+ }
+ // CHECK-LABEL: define void @_ZN10array_dtor1iEv(
+ void i() {
+ // CHECK: %[[ARRAY:.*]] = alloca [3 x
+ // CHECK: br
+
+ // CHECK: call void @_ZN10array_dtor1SC1Ev(
+ // CHECK: br i1
+
+ // CHECK: call void @_ZN10array_dtor1fEPA3_NS_1SE(
+ // CHECK: br
+
+ // CHECK: call void @_ZN10array_dtor1SD1Ev(
+ // CHECK: br i1
+ f(&T{});
+
+ // CHECK: ret void
+ }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx0x-initializer-constructors.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx0x-initializer-constructors.cpp
new file mode 100644
index 0000000..f60536e
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cxx0x-initializer-constructors.cpp
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -std=c++11 -S -triple x86_64-none-linux-gnu -emit-llvm -o - %s | FileCheck %s
+
+struct S {
+ S(int x) { }
+ S(int x, double y, double z) { }
+};
+
+void fn1() {
+ // CHECK-LABEL: define void @_Z3fn1v
+ S s { 1 };
+ // CHECK: alloca %struct.S, align 1
+ // CHECK: call void @_ZN1SC1Ei(%struct.S* %s, i32 1)
+}
+
+void fn2() {
+ // CHECK-LABEL: define void @_Z3fn2v
+ S s { 1, 2.0, 3.0 };
+ // CHECK: alloca %struct.S, align 1
+ // CHECK: call void @_ZN1SC1Eidd(%struct.S* %s, i32 1, double 2.000000e+00, double 3.000000e+00)
+}
+
+void fn3() {
+ // CHECK-LABEL: define void @_Z3fn3v
+ S sa[] { { 1 }, { 2 }, { 3 } };
+ // CHECK: alloca [3 x %struct.S], align 1
+ // CHECK: call void @_ZN1SC1Ei(%struct.S* %{{.+}}, i32 1)
+ // CHECK: call void @_ZN1SC1Ei(%struct.S* %{{.+}}, i32 2)
+ // CHECK: call void @_ZN1SC1Ei(%struct.S* %{{.+}}, i32 3)
+}
+
+void fn4() {
+ // CHECK-LABEL: define void @_Z3fn4v
+ S sa[] { { 1, 2.0, 3.0 }, { 4, 5.0, 6.0 } };
+ // CHECK: alloca [2 x %struct.S], align 1
+ // CHECK: call void @_ZN1SC1Eidd(%struct.S* %{{.+}}, i32 1, double 2.000000e+00, double 3.000000e+00)
+ // CHECK: call void @_ZN1SC1Eidd(%struct.S* %{{.+}}, i32 4, double 5.000000e+00, double 6.000000e+00)
+}
+
+namespace TreeTransformBracedInit {
+ struct S {};
+ struct T { T(const S &); T(const T&); ~T(); };
+ void x(const T &);
+ template<typename> void foo(const S &s) {
+ // Instantiation of this expression used to lose the CXXBindTemporaryExpr
+ // node and thus not destroy the temporary.
+ x({s});
+ }
+ template void foo<void>(const S&);
+ // CHECK: define {{.*}} void @_ZN23TreeTransformBracedInit3fooIvEEvRKNS_1SE(
+ // CHECK: call void @_ZN23TreeTransformBracedInit1TC1ERKNS_1SE(
+ // CHECK-NEXT: call void @_ZN23TreeTransformBracedInit1xERKNS_1TE(
+ // CHECK-NEXT: call void @_ZN23TreeTransformBracedInit1TD1Ev(
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx0x-initializer-references.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx0x-initializer-references.cpp
new file mode 100644
index 0000000..595d27c
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cxx0x-initializer-references.cpp
@@ -0,0 +1,111 @@
+// RUN: %clang_cc1 -std=c++11 -S -triple armv7-none-eabi -fmerge-all-constants -emit-llvm -o - %s | FileCheck %s
+
+namespace reference {
+ struct A {
+ int i1, i2;
+ };
+
+ void single_init() {
+ // No superfluous instructions allowed here, they could be
+ // hiding extra temporaries.
+
+ // CHECK: store i32 1, i32*
+ // CHECK-NEXT: store i32* %{{.*}}, i32**
+ const int &cri2a = 1;
+
+ // CHECK-NEXT: store i32 1, i32*
+ // CHECK-NEXT: store i32* %{{.*}}, i32**
+ const int &cri1a = {1};
+
+ // CHECK-NEXT: store i32 1, i32*
+ int i = 1;
+ // CHECK-NEXT: store i32* %{{.*}}, i32**
+ int &ri1a = {i};
+
+ // CHECK-NEXT: bitcast
+ // CHECK-NEXT: memcpy
+ A a{1, 2};
+ // CHECK-NEXT: store %{{.*}}* %{{.*}}, %{{.*}}** %
+ A &ra1a = {a};
+
+ using T = A&;
+ // CHECK-NEXT: store %{{.*}}* %{{.*}}, %{{.*}}** %
+ A &ra1b = T{a};
+
+ // CHECK-NEXT: ret
+ }
+
+ void reference_to_aggregate(int i) {
+ // CHECK: getelementptr {{.*}}, i32 0, i32 0
+ // CHECK-NEXT: store i32 1
+ // CHECK-NEXT: getelementptr {{.*}}, i32 0, i32 1
+ // CHECK-NEXT: %[[I1:.*]] = load i32, i32*
+ // CHECK-NEXT: store i32 %[[I1]]
+ // CHECK-NEXT: store %{{.*}}* %{{.*}}, %{{.*}}** %{{.*}}, align
+ const A &ra1{1, i};
+
+ // CHECK-NEXT: getelementptr inbounds [3 x i32], [3 x i32]* %{{.*}}, i{{32|64}} 0, i{{32|64}} 0
+ // CHECK-NEXT: store i32 1
+ // CHECK-NEXT: getelementptr inbounds i32, i32* %{{.*}}, i{{32|64}} 1
+ // CHECK-NEXT: store i32 2
+ // CHECK-NEXT: getelementptr inbounds i32, i32* %{{.*}}, i{{32|64}} 1
+ // CHECK-NEXT: %[[I2:.*]] = load i32, i32*
+ // CHECK-NEXT: store i32 %[[I2]]
+ // CHECK-NEXT: store [3 x i32]* %{{.*}}, [3 x i32]** %{{.*}}, align
+ const int (&arrayRef)[] = {1, 2, i};
+
+ // CHECK: store %{{.*}}* @{{.*}}, %{{.*}}** %{{.*}}, align
+ const A &constra1{1, 2};
+
+ // CHECK-NEXT: store [3 x i32]* @{{.*}}, [3 x i32]** %{{.*}}, align
+ const int (&constarrayRef)[] = {1, 2, 3};
+
+ // CHECK-NEXT: ret
+ }
+
+ struct B {
+ B();
+ ~B();
+ };
+
+ void single_init_temp_cleanup()
+ {
+ // Ensure lifetime extension.
+
+ // CHECK: call %"struct.reference::B"* @_ZN9reference1BC1Ev
+ // CHECK-NEXT: store %{{.*}}* %{{.*}}, %{{.*}}** %
+ const B &rb{ B() };
+ // CHECK: call %"struct.reference::B"* @_ZN9reference1BD1Ev
+ }
+
+}
+
+namespace PR23165 {
+struct AbstractClass {
+ virtual void foo() const = 0;
+};
+
+struct ChildClass : public AbstractClass {
+ virtual void foo() const {}
+};
+
+void helper(const AbstractClass ¶m) {
+ param.foo();
+}
+
+void foo() {
+// CHECK-LABEL: @_ZN7PR231653fooEv
+// CHECK: call {{.*}} @_ZN7PR2316510ChildClassC1Ev
+// CHECK: call void @_ZN7PR231656helperERKNS_13AbstractClassE
+ helper(ChildClass());
+}
+
+struct S { struct T { int a; } t; mutable int b; };
+void f() {
+// CHECK-LABEL: _ZN7PR231651fEv
+// CHECK: alloca
+// CHECK: alloca
+// CHECK: store
+ const S::T &r = S().t;
+}
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx0x-initializer-scalars.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx0x-initializer-scalars.cpp
new file mode 100644
index 0000000..10c6966
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cxx0x-initializer-scalars.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -std=c++11 -S -emit-llvm -o - %s | FileCheck %s
+
+void f()
+{
+ // CHECK: store i32 0
+ int i{};
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-pr12086.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-pr12086.cpp
new file mode 100644
index 0000000..da0c47b
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-pr12086.cpp
@@ -0,0 +1,132 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-STATIC-BL
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -emit-llvm -o - %s -Dconstexpr= | FileCheck %s --check-prefix=CHECK-DYNAMIC-BL
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -emit-llvm -o - %s -DUSE_END | FileCheck %s --check-prefix=CHECK-STATIC-BE
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -emit-llvm -o - %s -DUSE_END -Dconstexpr= | FileCheck %s --check-prefix=CHECK-DYNAMIC-BE
+
+namespace std {
+ typedef decltype(sizeof(int)) size_t;
+
+ template <class _E>
+ class initializer_list
+ {
+ const _E* __begin_;
+#ifdef USE_END
+ const _E* __end_;
+#else
+ size_t __size_;
+#endif
+
+ constexpr initializer_list(const _E* __b, size_t __s)
+ : __begin_(__b),
+#ifdef USE_END
+ __end_(__b + __s)
+#else
+ __size_(__s)
+#endif
+ {}
+
+ public:
+ typedef _E value_type;
+ typedef const _E& reference;
+ typedef const _E& const_reference;
+ typedef size_t size_type;
+
+ typedef const _E* iterator;
+ typedef const _E* const_iterator;
+
+#ifdef USE_END
+ constexpr initializer_list() : __begin_(nullptr), __end_(nullptr) {}
+
+ size_t size() const {return __end_ - __begin_;}
+ const _E* begin() const {return __begin_;}
+ const _E* end() const {return __end_;}
+#else
+ constexpr initializer_list() : __begin_(nullptr), __size_(0) {}
+
+ size_t size() const {return __size_;}
+ const _E* begin() const {return __begin_;}
+ const _E* end() const {return __begin_ + __size_;}
+#endif
+ };
+}
+
+constexpr int a = 2, b = 4, c = 6;
+std::initializer_list<std::initializer_list<int>> nested = {
+ {1, a}, {3, b}, {5, c}
+};
+
+// CHECK-STATIC-BL: @_ZGR6nested0_ = internal constant [2 x i32] [i32 1, i32 2], align 4
+// CHECK-STATIC-BL: @_ZGR6nested1_ = internal constant [2 x i32] [i32 3, i32 4], align 4
+// CHECK-STATIC-BL: @_ZGR6nested2_ = internal constant [2 x i32] [i32 5, i32 6], align 4
+// CHECK-STATIC-BL: @_ZGR6nested_ = internal constant [3 x {{.*}}] [
+// CHECK-STATIC-BL: {{.*}} { i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested0_, i32 0, i32 0), i64 2 },
+// CHECK-STATIC-BL: {{.*}} { i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested1_, i32 0, i32 0), i64 2 },
+// CHECK-STATIC-BL: {{.*}} { i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested2_, i32 0, i32 0), i64 2 }
+// CHECK-STATIC-BL: ], align 8
+// CHECK-STATIC-BL: @nested = global {{.*}} { {{.*}} getelementptr inbounds ([3 x {{.*}}], [3 x {{.*}}]* @_ZGR6nested_, i32 0, i32 0), i64 3 }, align 8
+
+// CHECK-DYNAMIC-BL: @nested = global
+// CHECK-DYNAMIC-BL: @_ZGR6nested_ = internal global [3 x
+// CHECK-DYNAMIC-BL: @_ZGR6nested0_ = internal global [2 x i32] zeroinitializer
+// CHECK-DYNAMIC-BL: @_ZGR6nested1_ = internal global [2 x i32] zeroinitializer
+// CHECK-DYNAMIC-BL: @_ZGR6nested2_ = internal global [2 x i32] zeroinitializer
+// CHECK-DYNAMIC-BL: store i32 1, i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested0_, i64 0, i64 0)
+// CHECK-DYNAMIC-BL: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested0_, i64 0, i64 1)
+// CHECK-DYNAMIC-BL: store i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested0_, i64 0, i64 0),
+// CHECK-DYNAMIC-BL: i32** getelementptr inbounds ([3 x {{.*}}], [3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 0, i32 0), align 8
+// CHECK-DYNAMIC-BL: store i64 2, i64* getelementptr inbounds ([3 x {{.*}}], [3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 0, i32 1), align 8
+// CHECK-DYNAMIC-BL: store i32 3, i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested1_, i64 0, i64 0)
+// CHECK-DYNAMIC-BL: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested1_, i64 0, i64 1)
+// CHECK-DYNAMIC-BL: store i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested1_, i64 0, i64 0),
+// CHECK-DYNAMIC-BL: i32** getelementptr inbounds ([3 x {{.*}}], [3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 1, i32 0), align 8
+// CHECK-DYNAMIC-BL: store i64 2, i64* getelementptr inbounds ([3 x {{.*}}], [3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 1, i32 1), align 8
+// CHECK-DYNAMIC-BL: store i32 5, i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested2_, i64 0, i64 0)
+// CHECK-DYNAMIC-BL: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested2_, i64 0, i64 1)
+// CHECK-DYNAMIC-BL: store i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested2_, i64 0, i64 0),
+// CHECK-DYNAMIC-BL: i32** getelementptr inbounds ([3 x {{.*}}], [3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 2, i32 0), align 8
+// CHECK-DYNAMIC-BL: store i64 2, i64* getelementptr inbounds ([3 x {{.*}}], [3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 2, i32 1), align 8
+// CHECK-DYNAMIC-BL: store {{.*}}* getelementptr inbounds ([3 x {{.*}}], [3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 0),
+// CHECK-DYNAMIC-BL: {{.*}}** getelementptr inbounds ({{.*}}, {{.*}}* @nested, i32 0, i32 0), align 8
+// CHECK-DYNAMIC-BL: store i64 3, i64* getelementptr inbounds ({{.*}}, {{.*}}* @nested, i32 0, i32 1), align 8
+
+// CHECK-STATIC-BE: @_ZGR6nested0_ = internal constant [2 x i32] [i32 1, i32 2], align 4
+// CHECK-STATIC-BE: @_ZGR6nested1_ = internal constant [2 x i32] [i32 3, i32 4], align 4
+// CHECK-STATIC-BE: @_ZGR6nested2_ = internal constant [2 x i32] [i32 5, i32 6], align 4
+// CHECK-STATIC-BE: @_ZGR6nested_ = internal constant [3 x {{.*}}] [
+// CHECK-STATIC-BE: {{.*}} { i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested0_, i32 0, i32 0),
+// CHECK-STATIC-BE: i32* bitcast (i8* getelementptr (i8, i8* bitcast ([2 x i32]* @_ZGR6nested0_ to i8*), i64 8) to i32*) }
+// CHECK-STATIC-BE: {{.*}} { i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested1_, i32 0, i32 0),
+// CHECK-STATIC-BE: i32* bitcast (i8* getelementptr (i8, i8* bitcast ([2 x i32]* @_ZGR6nested1_ to i8*), i64 8) to i32*) }
+// CHECK-STATIC-BE: {{.*}} { i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested2_, i32 0, i32 0),
+// CHECK-STATIC-BE: i32* bitcast (i8* getelementptr (i8, i8* bitcast ([2 x i32]* @_ZGR6nested2_ to i8*), i64 8) to i32*) }
+// CHECK-STATIC-BE: ], align 8
+// CHECK-STATIC-BE: @nested = global {{.*}} { {{.*}} getelementptr inbounds ([3 x {{.*}}], [3 x {{.*}}]* @_ZGR6nested_, i32 0, i32 0),
+// CHECK-STATIC-BE: {{.*}} bitcast ({{.*}}* getelementptr (i8, i8* bitcast ([3 x {{.*}}]* @_ZGR6nested_ to i8*), i64 48) to {{.*}}*) }
+
+// CHECK-DYNAMIC-BE: @nested = global
+// CHECK-DYNAMIC-BE: @_ZGR6nested_ = internal global [3 x
+// CHECK-DYNAMIC-BE: @_ZGR6nested0_ = internal global [2 x i32] zeroinitializer
+// CHECK-DYNAMIC-BE: @_ZGR6nested1_ = internal global [2 x i32] zeroinitializer
+// CHECK-DYNAMIC-BE: @_ZGR6nested2_ = internal global [2 x i32] zeroinitializer
+// CHECK-DYNAMIC-BE: store i32 1, i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested0_, i64 0, i64 0)
+// CHECK-DYNAMIC-BE: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested0_, i64 0, i64 1)
+// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested0_, i64 0, i64 0),
+// CHECK-DYNAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}], [3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 0, i32 0), align 8
+// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested0_, i64 1, i64 0),
+// CHECK-DYNAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}], [3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 0, i32 1), align 8
+// CHECK-DYNAMIC-BE: store i32 3, i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested1_, i64 0, i64 0)
+// CHECK-DYNAMIC-BE: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested1_, i64 0, i64 1)
+// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested1_, i64 0, i64 0),
+// CHECK-DYNAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}], [3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 1, i32 0), align 8
+// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested1_, i64 1, i64 0),
+// CHECK-DYNAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}], [3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 1, i32 1), align 8
+// CHECK-DYNAMIC-BE: store i32 5, i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested2_, i64 0, i64 0)
+// CHECK-DYNAMIC-BE: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested2_, i64 0, i64 1)
+// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested2_, i64 0, i64 0),
+// CHECK-DYNAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}], [3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 2, i32 0), align 8
+// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested2_, i64 1, i64 0),
+// CHECK-DYNAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}], [3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 2, i32 1), align 8
+// CHECK-DYNAMIC-BE: store {{.*}}* getelementptr inbounds ([3 x {{.*}}], [3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 0),
+// CHECK-DYNAMIC-BE: {{.*}}** getelementptr inbounds ({{.*}}, {{.*}}* @nested, i32 0, i32 0), align 8
+// CHECK-DYNAMIC-BE: store {{.*}}* getelementptr inbounds ([3 x {{.*}}], [3 x {{.*}}]* @_ZGR6nested_, i64 1, i64 0),
+// CHECK-DYNAMIC-BE: {{.*}}** getelementptr inbounds ({{.*}}, {{.*}}* @nested, i32 0, i32 1), align 8
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-startend.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-startend.cpp
new file mode 100644
index 0000000..46ad686
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-startend.cpp
@@ -0,0 +1,85 @@
+// RUN: %clang_cc1 -std=c++11 -S -triple x86_64-none-linux-gnu -emit-llvm -o - %s | FileCheck %s
+
+namespace std {
+ typedef decltype(sizeof(int)) size_t;
+
+ // libc++'s implementation with __size_ replaced by __end_
+ template <class _E>
+ class initializer_list
+ {
+ const _E* __begin_;
+ const _E* __end_;
+
+ initializer_list(const _E* __b, const _E* __e)
+ : __begin_(__b),
+ __end_(__e)
+ {}
+
+ public:
+ typedef _E value_type;
+ typedef const _E& reference;
+ typedef const _E& const_reference;
+ typedef size_t size_type;
+
+ typedef const _E* iterator;
+ typedef const _E* const_iterator;
+
+ initializer_list() : __begin_(nullptr), __end_(nullptr) {}
+
+ size_t size() const {return __end_ - __begin_;}
+ const _E* begin() const {return __begin_;}
+ const _E* end() const {return __end_;}
+ };
+}
+
+// CHECK: @_ZGR15globalInitList1_ = internal constant [3 x i32] [i32 1, i32 2, i32 3]
+// CHECK: @globalInitList1 = global {{[^ ]+}} { i32* getelementptr inbounds ([3 x i32], [3 x i32]* @_ZGR15globalInitList1_, {{[^)]*}}), i32*
+std::initializer_list<int> globalInitList1 = {1, 2, 3};
+
+void fn1(int i) {
+ // CHECK-LABEL: define void @_Z3fn1i
+ // temporary array
+ // CHECK: [[array:%[^ ]+]] = alloca [3 x i32]
+ // CHECK: getelementptr inbounds [3 x i32], [3 x i32]* [[array]], i{{32|64}} 0
+ // CHECK-NEXT: store i32 1, i32*
+ // CHECK-NEXT: getelementptr
+ // CHECK-NEXT: store
+ // CHECK-NEXT: getelementptr
+ // CHECK-NEXT: load
+ // CHECK-NEXT: store
+ // init the list
+ // CHECK-NEXT: getelementptr
+ // CHECK-NEXT: getelementptr inbounds [3 x i32], [3 x i32]*
+ // CHECK-NEXT: store i32*
+ // CHECK-NEXT: getelementptr
+ // CHECK-NEXT: getelementptr inbounds [3 x i32], [3 x i32]* [[array]], i{{32|64}} 0, i{{32|64}} 3
+ // CHECK-NEXT: store i32*
+ std::initializer_list<int> intlist{1, 2, i};
+}
+
+struct destroyme1 {
+ ~destroyme1();
+};
+struct destroyme2 {
+ ~destroyme2();
+};
+
+
+void fn2() {
+ // CHECK-LABEL: define void @_Z3fn2v
+ void target(std::initializer_list<destroyme1>);
+ // objects should be destroyed before dm2, after call returns
+ target({ destroyme1(), destroyme1() });
+ // CHECK: call void @_ZN10destroyme1D1Ev
+ destroyme2 dm2;
+ // CHECK: call void @_ZN10destroyme2D1Ev
+}
+
+void fn3() {
+ // CHECK-LABEL: define void @_Z3fn3v
+ // objects should be destroyed after dm2
+ auto list = { destroyme1(), destroyme1() };
+ destroyme2 dm2;
+ // CHECK: call void @_ZN10destroyme2D1Ev
+ // CHECK: call void @_ZN10destroyme1D1Ev
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
new file mode 100644
index 0000000..e3c7e26
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
@@ -0,0 +1,508 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-none-linux-gnu -fmerge-all-constants -emit-llvm -o - %s | FileCheck -check-prefixes=X86,CHECK %s
+// RUN: %clang_cc1 -std=c++11 -triple amdgcn-amd-amdhsa -DNO_TLS -fmerge-all-constants -emit-llvm -o - %s | FileCheck -check-prefixes=AMDGCN,CHECK %s
+
+namespace std {
+ typedef decltype(sizeof(int)) size_t;
+
+ // libc++'s implementation
+ template <class _E>
+ class initializer_list
+ {
+ const _E* __begin_;
+ size_t __size_;
+
+ initializer_list(const _E* __b, size_t __s)
+ : __begin_(__b),
+ __size_(__s)
+ {}
+
+ public:
+ typedef _E value_type;
+ typedef const _E& reference;
+ typedef const _E& const_reference;
+ typedef size_t size_type;
+
+ typedef const _E* iterator;
+ typedef const _E* const_iterator;
+
+ initializer_list() : __begin_(nullptr), __size_(0) {}
+
+ size_t size() const {return __size_;}
+ const _E* begin() const {return __begin_;}
+ const _E* end() const {return __begin_ + __size_;}
+ };
+}
+
+struct destroyme1 {
+ ~destroyme1();
+};
+struct destroyme2 {
+ ~destroyme2();
+};
+struct witharg1 {
+ witharg1(const destroyme1&);
+ ~witharg1();
+};
+struct wantslist1 {
+ wantslist1(std::initializer_list<destroyme1>);
+ ~wantslist1();
+};
+// X86: @_ZGR15globalInitList1_ = internal constant [3 x i32] [i32 1, i32 2, i32 3]
+// X86: @globalInitList1 = global %{{[^ ]+}} { i32* getelementptr inbounds ([3 x i32], [3 x i32]* @_ZGR15globalInitList1_, i32 0, i32 0), i{{32|64}} 3 }
+// AMDGCN: @_ZGR15globalInitList1_ = internal addrspace(1) constant [3 x i32] [i32 1, i32 2, i32 3]
+// AMDGCN: @globalInitList1 = addrspace(1) global %{{[^ ]+}} { i32* addrspacecast (i32 addrspace(1)* getelementptr inbounds ([3 x i32], [3 x i32] addrspace(1)* @_ZGR15globalInitList1_, i32 0, i32 0) to i32*), i{{32|64}} 3 }
+std::initializer_list<int> globalInitList1 = {1, 2, 3};
+
+#ifndef NO_TLS
+namespace thread_local_global_array {
+// FIXME: We should be able to constant-evaluate this even though the
+// initializer is not a constant expression (pointers to thread_local
+// objects aren't really a problem).
+//
+// X86: @_ZN25thread_local_global_array1xE = thread_local global
+// X86: @_ZGRN25thread_local_global_array1xE_ = internal thread_local constant [4 x i32] [i32 1, i32 2, i32 3, i32 4]
+std::initializer_list<int> thread_local x = {1, 2, 3, 4};
+}
+#endif
+
+// X86: @globalInitList2 = global %{{[^ ]+}} zeroinitializer
+// X86: @_ZGR15globalInitList2_ = internal global [2 x %[[WITHARG:[^ ]*]]] zeroinitializer
+// AMDGCN: @globalInitList2 = addrspace(1) global %{{[^ ]+}} zeroinitializer
+// AMDGCN: @_ZGR15globalInitList2_ = internal addrspace(1) global [2 x %[[WITHARG:[^ ]*]]] zeroinitializer
+
+// X86: @_ZN15partly_constant1kE = global i32 0, align 4
+// X86: @_ZN15partly_constant2ilE = global {{.*}} null, align 8
+// X86: @[[PARTLY_CONSTANT_OUTER:_ZGRN15partly_constant2ilE_]] = internal global {{.*}} zeroinitializer, align 8
+// X86: @[[PARTLY_CONSTANT_INNER:_ZGRN15partly_constant2ilE0_]] = internal global [3 x {{.*}}] zeroinitializer, align 8
+// X86: @[[PARTLY_CONSTANT_FIRST:_ZGRN15partly_constant2ilE1_]] = internal constant [3 x i32] [i32 1, i32 2, i32 3], align 4
+// X86: @[[PARTLY_CONSTANT_SECOND:_ZGRN15partly_constant2ilE2_]] = internal global [2 x i32] zeroinitializer, align 4
+// X86: @[[PARTLY_CONSTANT_THIRD:_ZGRN15partly_constant2ilE3_]] = internal constant [4 x i32] [i32 5, i32 6, i32 7, i32 8], align 4
+// AMDGCN: @_ZN15partly_constant1kE = addrspace(1) global i32 0, align 4
+// AMDGCN: @_ZN15partly_constant2ilE = addrspace(4) global {{.*}} null, align 8
+// AMDGCN: @[[PARTLY_CONSTANT_OUTER:_ZGRN15partly_constant2ilE_]] = internal addrspace(4) global {{.*}} zeroinitializer, align 8
+// AMDGCN: @[[PARTLY_CONSTANT_INNER:_ZGRN15partly_constant2ilE0_]] = internal addrspace(4) global [3 x {{.*}}] zeroinitializer, align 8
+// AMDGCN: @[[PARTLY_CONSTANT_FIRST:_ZGRN15partly_constant2ilE1_]] = internal addrspace(4) constant [3 x i32] [i32 1, i32 2, i32 3], align 4
+// AMDGCN: @[[PARTLY_CONSTANT_SECOND:_ZGRN15partly_constant2ilE2_]] = internal addrspace(4) global [2 x i32] zeroinitializer, align 4
+// AMDGCN: @[[PARTLY_CONSTANT_THIRD:_ZGRN15partly_constant2ilE3_]] = internal addrspace(4) constant [4 x i32] [i32 5, i32 6, i32 7, i32 8], align 4
+
+// X86: @[[REFTMP1:.*]] = private constant [2 x i32] [i32 42, i32 43], align 4
+// X86: @[[REFTMP2:.*]] = private constant [3 x %{{.*}}] [%{{.*}} { i32 1 }, %{{.*}} { i32 2 }, %{{.*}} { i32 3 }], align 4
+// AMDGCN: @[[REFTMP1:.*]] = private addrspace(4) constant [2 x i32] [i32 42, i32 43], align 4
+// AMDGCN: @[[REFTMP2:.*]] = private addrspace(4) constant [3 x %{{.*}}] [%{{.*}} { i32 1 }, %{{.*}} { i32 2 }, %{{.*}} { i32 3 }], align 4
+
+// CHECK: appending global
+
+// thread_local initializer:
+// X86-LABEL: define internal void @__cxx_global_var_init
+// X86: store i32* getelementptr inbounds ([4 x i32], [4 x i32]* @_ZGRN25thread_local_global_array1xE_, i64 0, i64 0),
+// X86: i32** getelementptr inbounds ({{.*}}, {{.*}}* @_ZN25thread_local_global_array1xE, i32 0, i32 0), align 8
+// X86: store i64 4, i64* getelementptr inbounds ({{.*}}, {{.*}}* @_ZN25thread_local_global_array1xE, i32 0, i32 1), align 8
+
+// CHECK-LABEL: define internal void @__cxx_global_var_init
+// X86: call void @_ZN8witharg1C1ERK10destroyme1(%[[WITHARG]]* getelementptr inbounds ([2 x %[[WITHARG]]], [2 x %[[WITHARG]]]* @_ZGR15globalInitList2_, i{{32|64}} 0, i{{32|64}} 0
+// X86: call void @_ZN8witharg1C1ERK10destroyme1(%[[WITHARG]]* getelementptr inbounds ([2 x %[[WITHARG]]], [2 x %[[WITHARG]]]* @_ZGR15globalInitList2_, i{{32|64}} 0, i{{32|64}} 1
+// AMDGCN: call void @_ZN8witharg1C1ERK10destroyme1(%[[WITHARG]]* getelementptr inbounds ([2 x %[[WITHARG]]], [2 x %[[WITHARG]]]* addrspacecast ({{[^@]+}} @_ZGR15globalInitList2_ {{[^)]+}}), i{{32|64}} 0, i{{32|64}} 0
+// AMDGCN: call void @_ZN8witharg1C1ERK10destroyme1(%[[WITHARG]]* getelementptr inbounds ([2 x %[[WITHARG]]], [2 x %[[WITHARG]]]* addrspacecast ({{[^@]+}} @_ZGR15globalInitList2_ {{[^)]+}}), i{{32|64}} 0, i{{32|64}} 1
+// CHECK: call i32 @__cxa_atexit
+// X86: store %[[WITHARG]]* getelementptr inbounds ([2 x %[[WITHARG]]], [2 x %[[WITHARG]]]* @_ZGR15globalInitList2_, i64 0, i64 0),
+// X86: %[[WITHARG]]** getelementptr inbounds (%{{.*}}, %{{.*}}* @globalInitList2, i32 0, i32 0), align 8
+// X86: store i64 2, i64* getelementptr inbounds (%{{.*}}, %{{.*}}* @globalInitList2, i32 0, i32 1), align 8
+// AMDGCN: store %[[WITHARG]]* getelementptr inbounds ([2 x %[[WITHARG]]], [2 x %[[WITHARG]]]* addrspacecast ({{[^@]+}} @_ZGR15globalInitList2_ {{[^)]+}}), i64 0, i64 0),
+// AMDGCN: %[[WITHARG]]** getelementptr inbounds (%{{.*}}, %{{.*}}* addrspacecast ({{[^@]+}} @globalInitList2 {{[^)]+}}), i32 0, i32 0), align 8
+// AMDGCN: store i64 2, i64* getelementptr inbounds (%{{.*}}, %{{.*}}* addrspacecast ({{[^@]+}} @globalInitList2 {{[^)]+}}), i32 0, i32 1), align 8
+// CHECK: call void @_ZN10destroyme1D1Ev
+// CHECK-NEXT: call void @_ZN10destroyme1D1Ev
+// CHECK-NEXT: ret void
+std::initializer_list<witharg1> globalInitList2 = {
+ witharg1(destroyme1()), witharg1(destroyme1())
+};
+
+void fn1(int i) {
+ // CHECK-LABEL: define void @_Z3fn1i
+ // temporary array
+ // X86: [[array:%[^ ]+]] = alloca [3 x i32]
+ // AMDGCN: [[alloca:%[^ ]+]] = alloca [3 x i32], align 4, addrspace(5)
+ // AMDGCN: [[array:%[^ ]+]] = addrspacecast [3 x i32] addrspace(5)* [[alloca]] to [3 x i32]*
+ // CHECK: getelementptr inbounds [3 x i32], [3 x i32]* [[array]], i{{32|64}} 0
+ // CHECK-NEXT: store i32 1, i32*
+ // CHECK-NEXT: getelementptr
+ // CHECK-NEXT: store
+ // CHECK-NEXT: getelementptr
+ // CHECK-NEXT: load
+ // CHECK-NEXT: store
+ // init the list
+ // CHECK-NEXT: getelementptr
+ // CHECK-NEXT: getelementptr inbounds [3 x i32], [3 x i32]*
+ // CHECK-NEXT: store i32*
+ // CHECK-NEXT: getelementptr
+ // CHECK-NEXT: store i{{32|64}} 3
+ std::initializer_list<int> intlist{1, 2, i};
+}
+
+void fn2() {
+ // CHECK-LABEL: define void @_Z3fn2v
+ void target(std::initializer_list<destroyme1>);
+ // objects should be destroyed before dm2, after call returns
+ // CHECK: call void @_Z6targetSt16initializer_listI10destroyme1E
+ target({ destroyme1(), destroyme1() });
+ // CHECK: call void @_ZN10destroyme1D1Ev
+ destroyme2 dm2;
+ // CHECK: call void @_ZN10destroyme2D1Ev
+}
+
+void fn3() {
+ // CHECK-LABEL: define void @_Z3fn3v
+ // objects should be destroyed after dm2
+ auto list = { destroyme1(), destroyme1() };
+ destroyme2 dm2;
+ // CHECK: call void @_ZN10destroyme2D1Ev
+ // CHECK: call void @_ZN10destroyme1D1Ev
+}
+
+void fn4() {
+ // CHECK-LABEL: define void @_Z3fn4v
+ void target(std::initializer_list<witharg1>);
+ // objects should be destroyed before dm2, after call returns
+ // CHECK: call void @_ZN8witharg1C1ERK10destroyme1
+ // CHECK: call void @_Z6targetSt16initializer_listI8witharg1E
+ target({ witharg1(destroyme1()), witharg1(destroyme1()) });
+ // CHECK: call void @_ZN8witharg1D1Ev
+ // CHECK: call void @_ZN10destroyme1D1Ev
+ destroyme2 dm2;
+ // CHECK: call void @_ZN10destroyme2D1Ev
+}
+
+void fn5() {
+ // CHECK-LABEL: define void @_Z3fn5v
+ // temps should be destroyed before dm2
+ // objects should be destroyed after dm2
+ // CHECK: call void @_ZN8witharg1C1ERK10destroyme1
+ auto list = { witharg1(destroyme1()), witharg1(destroyme1()) };
+ // CHECK: call void @_ZN10destroyme1D1Ev
+ destroyme2 dm2;
+ // CHECK: call void @_ZN10destroyme2D1Ev
+ // CHECK: call void @_ZN8witharg1D1Ev
+}
+
+void fn6() {
+ // CHECK-LABEL: define void @_Z3fn6v
+ void target(const wantslist1&);
+ // objects should be destroyed before dm2, after call returns
+ // CHECK: call void @_ZN10wantslist1C1ESt16initializer_listI10destroyme1E
+ // CHECK: call void @_Z6targetRK10wantslist1
+ target({ destroyme1(), destroyme1() });
+ // CHECK: call void @_ZN10wantslist1D1Ev
+ // CHECK: call void @_ZN10destroyme1D1Ev
+ destroyme2 dm2;
+ // CHECK: call void @_ZN10destroyme2D1Ev
+}
+void fn7() {
+ // CHECK-LABEL: define void @_Z3fn7v
+ // temps should be destroyed before dm2
+ // object should be destroyed after dm2
+ // CHECK: call void @_ZN10wantslist1C1ESt16initializer_listI10destroyme1E
+ wantslist1 wl = { destroyme1(), destroyme1() };
+ // CHECK: call void @_ZN10destroyme1D1Ev
+ destroyme2 dm2;
+ // CHECK: call void @_ZN10destroyme2D1Ev
+ // CHECK: call void @_ZN10wantslist1D1Ev
+}
+
+void fn8() {
+ // CHECK-LABEL: define void @_Z3fn8v
+ void target(std::initializer_list<std::initializer_list<destroyme1>>);
+ // objects should be destroyed before dm2, after call returns
+ // CHECK: call void @_Z6targetSt16initializer_listIS_I10destroyme1EE
+ std::initializer_list<destroyme1> inner;
+ target({ inner, { destroyme1() } });
+ // CHECK: call void @_ZN10destroyme1D1Ev
+ // Only one destroy loop, since only one inner init list is directly inited.
+ // CHECK-NOT: call void @_ZN10destroyme1D1Ev
+ destroyme2 dm2;
+ // CHECK: call void @_ZN10destroyme2D1Ev
+}
+
+void fn9() {
+ // CHECK-LABEL: define void @_Z3fn9v
+ // objects should be destroyed after dm2
+ std::initializer_list<destroyme1> inner;
+ std::initializer_list<std::initializer_list<destroyme1>> list =
+ { inner, { destroyme1() } };
+ destroyme2 dm2;
+ // CHECK: call void @_ZN10destroyme2D1Ev
+ // CHECK: call void @_ZN10destroyme1D1Ev
+ // Only one destroy loop, since only one inner init list is directly inited.
+ // CHECK-NOT: call void @_ZN10destroyme1D1Ev
+ // CHECK: ret void
+}
+
+void fn10(int i) {
+ // CHECK-LABEL: define void @_Z4fn10i
+ // CHECK: alloca [3 x i32]
+ // CHECK: call i8* @_Znw{{[jm]}}
+ // CHECK: store i32 %
+ // CHECK: store i32 2
+ // CHECK: store i32 3
+ // CHECK: store i32*
+ (void) new std::initializer_list<int> {i, 2, 3};
+}
+
+void fn11() {
+ // CHECK-LABEL: define void @_Z4fn11v
+ (void) new std::initializer_list<destroyme1> {destroyme1(), destroyme1()};
+ // CHECK: call void @_ZN10destroyme1D1Ev
+ destroyme2 dm2;
+ // CHECK: call void @_ZN10destroyme2D1Ev
+}
+
+namespace PR12178 {
+ struct string {
+ string(int);
+ ~string();
+ };
+
+ struct pair {
+ string a;
+ int b;
+ };
+
+ struct map {
+ map(std::initializer_list<pair>);
+ };
+
+ map m{ {1, 2}, {3, 4} };
+}
+
+namespace rdar13325066 {
+ struct X { ~X(); };
+
+ // CHECK-LABEL: define void @_ZN12rdar133250664loopERNS_1XES1_
+ void loop(X &x1, X &x2) {
+ // CHECK: br label
+ // CHECK: br i1
+ // CHECK: br label
+ // CHECK: call void @_ZN12rdar133250661XD1Ev
+ // CHECK: br label
+ // CHECK: br label
+ // CHECK: call void @_ZN12rdar133250661XD1Ev
+ // CHECK: br i1
+ // CHECK: br label
+ // CHECK: ret void
+ for (X x : { x1, x2 }) { }
+ }
+}
+
+namespace dtors {
+ struct S {
+ S();
+ ~S();
+ };
+ void z();
+
+ // CHECK-LABEL: define void @_ZN5dtors1fEv(
+ void f() {
+ // CHECK: call void @_ZN5dtors1SC1Ev(
+ // CHECK: call void @_ZN5dtors1SC1Ev(
+ std::initializer_list<S>{ S(), S() };
+
+ // Destruction loop for underlying array.
+ // CHECK: br label
+ // CHECK: call void @_ZN5dtors1SD1Ev(
+ // CHECK: br i1
+
+ // CHECK: call void @_ZN5dtors1zEv(
+ z();
+
+ // CHECK-NOT: call void @_ZN5dtors1SD1Ev(
+ }
+
+ // CHECK-LABEL: define void @_ZN5dtors1gEv(
+ void g() {
+ // CHECK: call void @_ZN5dtors1SC1Ev(
+ // CHECK: call void @_ZN5dtors1SC1Ev(
+ auto x = std::initializer_list<S>{ S(), S() };
+
+ // Destruction loop for underlying array.
+ // CHECK: br label
+ // CHECK: call void @_ZN5dtors1SD1Ev(
+ // CHECK: br i1
+
+ // CHECK: call void @_ZN5dtors1zEv(
+ z();
+
+ // CHECK-NOT: call void @_ZN5dtors1SD1Ev(
+ }
+
+ // CHECK-LABEL: define void @_ZN5dtors1hEv(
+ void h() {
+ // CHECK: call void @_ZN5dtors1SC1Ev(
+ // CHECK: call void @_ZN5dtors1SC1Ev(
+ std::initializer_list<S> x = { S(), S() };
+
+ // CHECK-NOT: call void @_ZN5dtors1SD1Ev(
+
+ // CHECK: call void @_ZN5dtors1zEv(
+ z();
+
+ // Destruction loop for underlying array.
+ // CHECK: br label
+ // CHECK: call void @_ZN5dtors1SD1Ev(
+ // CHECK: br i1
+ }
+}
+
+namespace partly_constant {
+ int k;
+ std::initializer_list<std::initializer_list<int>> &&il = { { 1, 2, 3 }, { 4, k }, { 5, 6, 7, 8 } };
+ // First init list.
+ // CHECK-NOT: @[[PARTLY_CONSTANT_FIRST]],
+ // CHECK: store i32* getelementptr inbounds ({{.*}}, {{.*}}* {{.*}}@[[PARTLY_CONSTANT_FIRST]]{{.*}}, i64 0, i64 0),
+ // CHECK: i32** getelementptr inbounds ({{.*}}, {{.*}}* {{.*}}@[[PARTLY_CONSTANT_INNER]]{{.*}}, i64 0, i64 0, i32 0)
+ // CHECK: store i64 3, i64* getelementptr inbounds ({{.*}}, {{.*}}* {{.*}}@[[PARTLY_CONSTANT_INNER]]{{.*}}, i64 0, i64 0, i32 1)
+ // CHECK-NOT: @[[PARTLY_CONSTANT_FIRST]],
+ //
+ // Second init list array (non-constant).
+ // CHECK: store i32 4, i32* getelementptr inbounds ({{.*}}, {{.*}}* {{.*}}@[[PARTLY_CONSTANT_SECOND]]{{.*}}, i64 0, i64 0)
+ // CHECK: load i32, i32* {{.*}}@_ZN15partly_constant1kE
+ // CHECK: store i32 {{.*}}, i32* getelementptr inbounds ({{.*}}, {{.*}}* {{.*}}@[[PARTLY_CONSTANT_SECOND]]{{.*}}, i64 0, i64 1)
+ //
+ // Second init list.
+ // CHECK: store i32* getelementptr inbounds ({{.*}}, {{.*}}* {{.*}}@[[PARTLY_CONSTANT_SECOND]]{{.*}}, i64 0, i64 0),
+ // CHECK: i32** getelementptr inbounds ({{.*}}, {{.*}}* {{.*}}@[[PARTLY_CONSTANT_INNER]]{{.*}}, i64 0, i64 1, i32 0)
+ // CHECK: store i64 2, i64* getelementptr inbounds ({{.*}}, {{.*}}* {{.*}}@[[PARTLY_CONSTANT_INNER]]{{.*}}, i64 0, i64 1, i32 1)
+ //
+ // Third init list.
+ // CHECK-NOT: @[[PARTLY_CONSTANT_THIRD]],
+ // CHECK: store i32* getelementptr inbounds ({{.*}}, {{.*}}* {{.*}}@[[PARTLY_CONSTANT_THIRD]]{{.*}}, i64 0, i64 0),
+ // CHECK: i32** getelementptr inbounds ({{.*}}, {{.*}}* {{.*}}@[[PARTLY_CONSTANT_INNER]]{{.*}}, i64 0, i64 2, i32 0)
+ // CHECK: store i64 4, i64* getelementptr inbounds ({{.*}}, {{.*}}* {{.*}}@[[PARTLY_CONSTANT_INNER]]{{.*}}, i64 0, i64 2, i32 1)
+ // CHECK-NOT: @[[PARTLY_CONSTANT_THIRD]],
+ //
+ // Outer init list.
+ // CHECK: store {{.*}}* getelementptr inbounds ({{.*}}, {{.*}}* {{.*}}@[[PARTLY_CONSTANT_INNER]]{{.*}}, i64 0, i64 0),
+ // CHECK: {{.*}}** getelementptr inbounds ({{.*}}, {{.*}}* {{.*}}@[[PARTLY_CONSTANT_OUTER]]{{.*}}, i32 0, i32 0)
+ // CHECK: store i64 3, i64* getelementptr inbounds ({{.*}}, {{.*}}* {{.*}}@[[PARTLY_CONSTANT_OUTER]]{{.*}}, i32 0, i32 1)
+ //
+ // 'il' reference.
+ // CHECK: store {{.*}}* {{.*}}@[[PARTLY_CONSTANT_OUTER]]{{.*}}, {{.*}}** {{.*}}@_ZN15partly_constant2ilE{{.*}}, align 8
+}
+namespace nested {
+ struct A { A(); ~A(); };
+ struct B { const A &a; ~B(); };
+ struct C { std::initializer_list<B> b; ~C(); };
+ void f();
+ // CHECK-LABEL: define void @_ZN6nested1gEv(
+ void g() {
+ // CHECK: call void @_ZN6nested1AC1Ev(
+ // CHECK-NOT: call
+ // CHECK: call void @_ZN6nested1AC1Ev(
+ // CHECK-NOT: call
+ const C &c { { { A() }, { A() } } };
+
+ // CHECK: call void @_ZN6nested1fEv(
+ // CHECK-NOT: call
+ f();
+
+ // CHECK: call void @_ZN6nested1CD1Ev(
+ // CHECK-NOT: call
+
+ // Destroy B[2] array.
+ // FIXME: This isn't technically correct: reverse construction order would
+ // destroy the second B then the second A then the first B then the first A.
+ // CHECK: call void @_ZN6nested1BD1Ev(
+ // CHECK-NOT: call
+ // CHECK: br
+
+ // CHECK-NOT: call
+ // CHECK: call void @_ZN6nested1AD1Ev(
+ // CHECK-NOT: call
+ // CHECK: call void @_ZN6nested1AD1Ev(
+ // CHECK-NOT: call
+ // CHECK: }
+ }
+}
+
+namespace DR1070 {
+ struct A {
+ A(std::initializer_list<int>);
+ };
+ struct B {
+ int i;
+ A a;
+ };
+ B b = {1};
+ struct C {
+ std::initializer_list<int> a;
+ B b;
+ std::initializer_list<double> c;
+ };
+ C c = {};
+}
+
+namespace ArrayOfInitList {
+ struct S {
+ S(std::initializer_list<int>);
+ };
+ S x[1] = {};
+}
+
+namespace PR20445 {
+ struct vector { vector(std::initializer_list<int>); };
+ struct MyClass { explicit MyClass(const vector &v); };
+ template<int x> void f() { new MyClass({42, 43}); }
+ template void f<0>();
+ // CHECK-LABEL: define {{.*}} @_ZN7PR204451fILi0EEEvv(
+ // CHECK: store i32* getelementptr inbounds ([2 x i32], [2 x i32]* {{.*}}@[[REFTMP1]]{{.*}}, i64 0, i64 0)
+ // CHECK: call void @_ZN7PR204456vectorC1ESt16initializer_listIiE(
+ // CHECK: call void @_ZN7PR204457MyClassC1ERKNS_6vectorE(
+}
+
+namespace ConstExpr {
+ class C {
+ int x;
+ public:
+ constexpr C(int x) : x(x) {}
+ };
+ void f(std::initializer_list<C>);
+ void g() {
+ // CHECK-LABEL: _ZN9ConstExpr1gEv
+ // CHECK: store %"class.ConstExpr::C"* getelementptr inbounds ([3 x %"class.ConstExpr::C"], [3 x %"class.ConstExpr::C"]* {{.*}}@[[REFTMP2]]{{.*}}, i64 0, i64 0)
+ // CHECK: call void @_ZN9ConstExpr1fESt16initializer_listINS_1CEE
+ f({C(1), C(2), C(3)});
+ }
+}
+
+namespace B19773010 {
+ template <class T1, class T2> struct pair {
+ T1 first;
+ T2 second;
+ constexpr pair() : first(), second() {}
+ constexpr pair(T1 a, T2 b) : first(a), second(b) {}
+ };
+
+ enum E { ENUM_CONSTANT };
+ struct testcase {
+ testcase(std::initializer_list<pair<const char *, E>>);
+ };
+ void f1() {
+ // CHECK-LABEL: @_ZN9B197730102f1Ev
+ testcase a{{"", ENUM_CONSTANT}};
+ // X86: store %"struct.B19773010::pair"* getelementptr inbounds ([1 x %"struct.B19773010::pair"], [1 x %"struct.B19773010::pair"]* bitcast ([1 x { i8*, i32 }]* @.ref.tmp{{.*}} to [1 x %"struct.B19773010::pair"]*), i64 0, i64 0), %"struct.B19773010::pair"** %{{.*}}, align 8
+ // AMDGCN: store %"struct.B19773010::pair"* getelementptr inbounds ([1 x %"struct.B19773010::pair"], [1 x %"struct.B19773010::pair"]* addrspacecast{{.*}} bitcast ([1 x { i8*, i32 }] addrspace(4)* @.ref.tmp{{.*}} to [1 x %"struct.B19773010::pair"] addrspace(4)*){{.*}}, i64 0, i64 0), %"struct.B19773010::pair"** %{{.*}}, align 8
+ }
+ void f2() {
+ // CHECK-LABEL: @_ZN9B197730102f2Ev
+ // X86: store %"struct.B19773010::pair"* getelementptr inbounds ([1 x %"struct.B19773010::pair"], [1 x %"struct.B19773010::pair"]* bitcast ([1 x { i8*, i32 }]* @_ZGRZN9B197730102f2EvE1p_ to [1 x %"struct.B19773010::pair"]*), i64 0, i64 0), %"struct.B19773010::pair"** getelementptr inbounds ([2 x %"class.std::initializer_list.10"], [2 x %"class.std::initializer_list.10"]* @_ZZN9B197730102f2EvE1p, i64 0, i64 1, i32 0), align 16
+ // AMDGCN: store %"struct.B19773010::pair"* getelementptr inbounds ([1 x %"struct.B19773010::pair"], [1 x %"struct.B19773010::pair"]* addrspacecast{{.*}} bitcast ([1 x { i8*, i32 }] addrspace(1)* @_ZGRZN9B197730102f2EvE1p_ to [1 x %"struct.B19773010::pair"] addrspace(1)*){{.*}}, i64 0, i64 0), %"struct.B19773010::pair"** getelementptr inbounds ([2 x %"class.std::initializer_list.10"], [2 x %"class.std::initializer_list.10"]* addrspacecast{{.*}}@_ZZN9B197730102f2EvE1p{{.*}}, i64 0, i64 1, i32 0), align 8
+ static std::initializer_list<pair<const char *, E>> a, p[2] =
+ {a, {{"", ENUM_CONSTANT}}};
+ }
+
+ void PR22940_helper(const pair<void*, int>&) { }
+ void PR22940() {
+ // CHECK-LABEL: @_ZN9B197730107PR22940Ev
+ // CHECK: call {{.*}} @_ZN9B197730104pairIPviEC{{.}}Ev(
+ // CHECK: call {{.*}} @_ZN9B1977301014PR22940_helperERKNS_4pairIPviEE(
+ PR22940_helper(pair<void*, int>());
+ }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx11-exception-spec.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx11-exception-spec.cpp
new file mode 100644
index 0000000..fbff078
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cxx11-exception-spec.cpp
@@ -0,0 +1,132 @@
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -verify -fexceptions -fcxx-exceptions -triple x86_64-linux-gnu | FileCheck %s
+// expected-no-diagnostics
+
+void h();
+
+template<typename T> void f() noexcept(sizeof(T) == 4) { h(); }
+template<typename T> void g() noexcept(sizeof(T) == 4);
+
+template<typename T> struct S {
+ static void f() noexcept(sizeof(T) == 4) { h(); }
+ static void g() noexcept(sizeof(T) == 4);
+};
+
+// CHECK: define {{.*}} @_Z1fIsEvv() [[NONE:#[0-9]+]] {
+template<> void f<short>() { h(); }
+// CHECK: define {{.*}} @_Z1fIA2_sEvv() [[NUW:#[0-9]+]] personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
+template<> void f<short[2]>() noexcept { h(); }
+
+// CHECK: define {{.*}} @_ZN1SIsE1fEv()
+// CHECK-NOT: [[NUW]]
+template<> void S<short>::f() { h(); }
+// CHECK: define {{.*}} @_ZN1SIA2_sE1fEv() [[NUW]]
+template<> void S<short[2]>::f() noexcept { h(); }
+
+// CHECK: define {{.*}} @_Z1fIDsEvv() [[NONE]] comdat {
+template void f<char16_t>();
+// CHECK: define {{.*}} @_Z1fIA2_DsEvv() [[NUW]] comdat personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
+template void f<char16_t[2]>();
+
+// CHECK: define {{.*}} @_ZN1SIDsE1fEv()
+// CHECK-NOT: [[NUW]]
+template void S<char16_t>::f();
+// CHECK: define {{.*}} @_ZN1SIA2_DsE1fEv() [[NUW]]
+template void S<char16_t[2]>::f();
+
+void h() {
+ // CHECK: define {{.*}} @_Z1fIiEvv() [[NUW]] comdat personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
+ f<int>();
+ // CHECK: define {{.*}} @_Z1fIA2_iEvv() [[NONE]] comdat {
+ f<int[2]>();
+
+ // CHECK: define {{.*}} @_ZN1SIiE1fEv() [[NUW]]
+ S<int>::f();
+ // CHECK: define {{.*}} @_ZN1SIA2_iE1fEv()
+ // CHECK-NOT: [[NUW]]
+ S<int[2]>::f();
+
+ // CHECK: define {{.*}} @_Z1fIfEvv() [[NUW]] comdat personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
+ void (*f1)() = &f<float>;
+ // CHECK: define {{.*}} @_Z1fIdEvv() [[NONE]] comdat {
+ void (*f2)() = &f<double>;
+
+ // CHECK: define {{.*}} @_ZN1SIfE1fEv() [[NUW]]
+ void (*f3)() = &S<float>::f;
+ // CHECK: define {{.*}} @_ZN1SIdE1fEv()
+ // CHECK-NOT: [[NUW]]
+ void (*f4)() = &S<double>::f;
+
+ // CHECK: define {{.*}} @_Z1fIA4_cEvv() [[NUW]] comdat personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
+ (void)&f<char[4]>;
+ // CHECK: define {{.*}} @_Z1fIcEvv() [[NONE]] comdat {
+ (void)&f<char>;
+
+ // CHECK: define {{.*}} @_ZN1SIA4_cE1fEv() [[NUW]]
+ (void)&S<char[4]>::f;
+ // CHECK: define {{.*}} @_ZN1SIcE1fEv()
+ // CHECK-NOT: [[NUW]]
+ (void)&S<char>::f;
+}
+
+// CHECK: define {{.*}} @_Z1iv
+void i() {
+ // CHECK: declare {{.*}} @_Z1gIiEvv() [[NUW2:#[0-9]+]]
+ g<int>();
+ // CHECK: declare {{.*}} @_Z1gIA2_iEvv()
+ // CHECK-NOT: [[NUW]]
+ g<int[2]>();
+
+ // CHECK: declare {{.*}} @_ZN1SIiE1gEv() [[NUW2]]
+ S<int>::g();
+ // CHECK: declare {{.*}} @_ZN1SIA2_iE1gEv()
+ // CHECK-NOT: [[NUW]]
+ S<int[2]>::g();
+
+ // CHECK: declare {{.*}} @_Z1gIfEvv() [[NUW2]]
+ void (*g1)() = &g<float>;
+ // CHECK: declare {{.*}} @_Z1gIdEvv()
+ // CHECK-NOT: [[NUW]]
+ void (*g2)() = &g<double>;
+
+ // CHECK: declare {{.*}} @_ZN1SIfE1gEv() [[NUW2]]
+ void (*g3)() = &S<float>::g;
+ // CHECK: declare {{.*}} @_ZN1SIdE1gEv()
+ // CHECK-NOT: [[NUW]]
+ void (*g4)() = &S<double>::g;
+
+ // CHECK: declare {{.*}} @_Z1gIA4_cEvv() [[NUW2]]
+ (void)&g<char[4]>;
+ // CHECK: declare {{.*}} @_Z1gIcEvv()
+ // CHECK-NOT: [[NUW]]
+ (void)&g<char>;
+
+ // CHECK: declare {{.*}} @_ZN1SIA4_cE1gEv() [[NUW2]]
+ (void)&S<char[4]>::g;
+ // CHECK: declare {{.*}} @_ZN1SIcE1gEv()
+ // CHECK-NOT: [[NUW]]
+ (void)&S<char>::g;
+}
+
+template<typename T> struct Nested {
+ template<bool b, typename U> void f() noexcept(sizeof(T) == sizeof(U));
+};
+
+// CHECK: define {{.*}} @_Z1jv
+void j() {
+ // CHECK: declare {{.*}} @_ZN6NestedIiE1fILb1EcEEvv(
+ // CHECK-NOT: [[NUW]]
+ Nested<int>().f<true, char>();
+ // CHECK: declare {{.*}} @_ZN6NestedIlE1fILb0ElEEvv({{.*}}) [[NUW2]]
+ Nested<long>().f<false, long>();
+}
+
+// CHECK: attributes [[NONE]] = { {{.*}} }
+// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} }
+// CHECK: attributes [[NUW2]] = { nounwind{{.*}} }
+
+
+
+namespace PR19190 {
+template <class T> struct DWFIterator { virtual void get() throw(int) = 0; };
+void foo(DWFIterator<int> *foo) { foo->get(); }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx11-extern-constexpr.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx11-extern-constexpr.cpp
new file mode 100644
index 0000000..6c52003
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cxx11-extern-constexpr.cpp
@@ -0,0 +1,68 @@
+// RUN: %clang_cc1 -std=c++11 %s -emit-llvm -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK --check-prefix=CXX11
+// RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK --check-prefix=CXX17
+
+struct A {
+ static const int Foo = 123;
+};
+// CHECK: @_ZN1A3FooE = constant i32 123, align 4
+const int *p = &A::Foo; // emit available_externally
+const int A::Foo; // convert to full definition
+
+struct PODWithInit {
+ int g = 42;
+ char h = 43;
+};
+struct CreatePOD {
+ // Deferred initialization of the structure here requires changing
+ // the type of the global variable: the initializer list does not include
+ // the tail padding.
+ // CXX11: @_ZN9CreatePOD3podE = available_externally constant { i32, i8 } { i32 42, i8 43 },
+ static constexpr PODWithInit pod{};
+};
+const int *p_pod = &CreatePOD::pod.g;
+
+struct Bar {
+ int b;
+};
+
+struct MutableBar {
+ mutable int b;
+};
+
+struct Foo {
+ // CXX11: @_ZN3Foo21ConstexprStaticMemberE = available_externally constant i32 42,
+ // CXX17: @_ZN3Foo21ConstexprStaticMemberE = linkonce_odr constant i32 42,
+ static constexpr int ConstexprStaticMember = 42;
+ // CHECK: @_ZN3Foo17ConstStaticMemberE = available_externally constant i32 43,
+ static const int ConstStaticMember = 43;
+
+ // CXX11: @_ZN3Foo23ConstStaticStructMemberE = available_externally constant %struct.Bar { i32 44 },
+ // CXX17: @_ZN3Foo23ConstStaticStructMemberE = linkonce_odr constant %struct.Bar { i32 44 },
+ static constexpr Bar ConstStaticStructMember = {44};
+
+ // CXX11: @_ZN3Foo34ConstexprStaticMutableStructMemberE = external global %struct.MutableBar,
+ // CXX17: @_ZN3Foo34ConstexprStaticMutableStructMemberE = linkonce_odr global %struct.MutableBar { i32 45 },
+ static constexpr MutableBar ConstexprStaticMutableStructMember = {45};
+};
+// CHECK: @_ZL15ConstStaticexpr = internal constant i32 46,
+static constexpr int ConstStaticexpr = 46;
+// CHECK: @_ZL9ConstExpr = internal constant i32 46, align 4
+static const int ConstExpr = 46;
+
+// CHECK: @_ZL21ConstexprStaticStruct = internal constant %struct.Bar { i32 47 },
+static constexpr Bar ConstexprStaticStruct = {47};
+
+// CHECK: @_ZL28ConstexprStaticMutableStruct = internal global %struct.MutableBar { i32 48 },
+static constexpr MutableBar ConstexprStaticMutableStruct = {48};
+
+void use(const int &);
+void foo() {
+ use(Foo::ConstexprStaticMember);
+ use(Foo::ConstStaticMember);
+ use(Foo::ConstStaticStructMember.b);
+ use(Foo::ConstexprStaticMutableStructMember.b);
+ use(ConstStaticexpr);
+ use(ConstExpr);
+ use(ConstexprStaticStruct.b);
+ use(ConstexprStaticMutableStruct.b);
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx11-initializer-aggregate.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx11-initializer-aggregate.cpp
new file mode 100644
index 0000000..325607f
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cxx11-initializer-aggregate.cpp
@@ -0,0 +1,121 @@
+// RUN: %clang_cc1 -std=c++11 -S -emit-llvm -o - %s -triple x86_64-linux-gnu | FileCheck %s
+
+struct A { int a, b; int f(); };
+
+namespace NonAggregateCopyInAggregateInit { // PR32044
+ struct A { constexpr A(int n) : x(n), y() {} int x, y; } extern a;
+ // CHECK-DAG: @_ZN31NonAggregateCopyInAggregateInit1bE = global %{{.*}} { %[[A:.*]]* @_ZN31NonAggregateCopyInAggregateInit1aE }
+ struct B { A &p; } b{{a}};
+ // CHECK-DAG: @_ZGRN31NonAggregateCopyInAggregateInit1cE_ = internal global %[[A]] { i32 1, i32 0 }
+ // CHECK-DAG: @_ZN31NonAggregateCopyInAggregateInit1cE = global %{{.*}} { %{{.*}}* @_ZGRN31NonAggregateCopyInAggregateInit1cE_ }
+ struct C { A &&p; } c{{1}};
+}
+
+namespace NearlyZeroInit {
+ // CHECK-DAG: @_ZN14NearlyZeroInit1aE = global {{.*}} <{ i32 1, i32 2, i32 3, [120 x i32] zeroinitializer }>
+ int a[123] = {1, 2, 3};
+ // CHECK-DAG: @_ZN14NearlyZeroInit1bE = global {{.*}} { i32 1, <{ i32, [2147483647 x i32] }> <{ i32 2, [2147483647 x i32] zeroinitializer }> }
+ struct B { int n; int arr[1024 * 1024 * 1024 * 2u]; } b = {1, {2}};
+}
+
+namespace PR37560 {
+ union U {
+ char x;
+ int a;
+ };
+ // FIXME: [dcl.init]p2, the padding bits of the union object should be
+ // initialized to 0, not undef, which would allow us to collapse the tail
+ // of these arrays to zeroinitializer.
+ // CHECK-DAG: @_ZN7PR375601cE = global <{ { i8, [3 x i8] } }> <{ { i8, [3 x i8] } { i8 0, [3 x i8] undef } }>
+ U c[1] = {};
+ // CHECK-DAG: @_ZN7PR375601dE = global {{.*}} <{ { i8, [3 x i8] } { i8 97, [3 x i8] undef }, %"{{[^"]*}}" { i32 123 }, { i8, [3 x i8] } { i8 98, [3 x i8] undef }, { i8, [3 x i8] } { i8 0, [3 x i8] undef },
+ U d[16] = {'a', {.a = 123}, 'b'};
+ // CHECK-DAG: @_ZN7PR375601eE = global {{.*}} <{ %"{{[^"]*}}" { i32 123 }, %"{{[^"]*}}" { i32 456 }, { i8, [3 x i8] } { i8 0, [3 x i8] undef },
+ U e[16] = {{.a = 123}, {.a = 456}};
+
+ union V {
+ int a;
+ char x;
+ };
+ // CHECK-DAG: @_ZN7PR375601fE = global [1 x %"{{[^"]*}}"] zeroinitializer
+ V f[1] = {};
+ // CHECK-DAG: @_ZN7PR375601gE = global {{.*}} <{ { i8, [3 x i8] } { i8 97, [3 x i8] undef }, %"{{[^"]*}}" { i32 123 }, { i8, [3 x i8] } { i8 98, [3 x i8] undef }, [13 x %"{{[^"]*}}"] zeroinitializer }>
+ V g[16] = {{.x = 'a'}, {.a = 123}, {.x = 'b'}};
+ // CHECK-DAG: @_ZN7PR375601hE = global {{.*}} <{ %"{{[^"]*}}" { i32 123 }, %"{{[^"]*}}" { i32 456 }, [14 x %"{{[^"]*}}"] zeroinitializer }>
+ V h[16] = {{.a = 123}, {.a = 456}};
+ // CHECK-DAG: @_ZN7PR375601iE = global [4 x %"{{[^"]*}}"] [%"{{[^"]*}}" { i32 123 }, %"{{[^"]*}}" { i32 456 }, %"{{[^"]*}}" zeroinitializer, %"{{[^"]*}}" zeroinitializer]
+ V i[4] = {{.a = 123}, {.a = 456}};
+}
+
+// CHECK-LABEL: define {{.*}}@_Z3fn1i(
+int fn1(int x) {
+ // CHECK: %[[INITLIST:.*]] = alloca %struct.A
+ // CHECK: %[[A:.*]] = getelementptr inbounds %struct.A, %struct.A* %[[INITLIST]], i32 0, i32 0
+ // CHECK: store i32 %{{.*}}, i32* %[[A]], align 4
+ // CHECK: %[[B:.*]] = getelementptr inbounds %struct.A, %struct.A* %[[INITLIST]], i32 0, i32 1
+ // CHECK: store i32 5, i32* %[[B]], align 4
+ // CHECK: call i32 @_ZN1A1fEv(%struct.A* %[[INITLIST]])
+ return A{x, 5}.f();
+}
+
+struct B { int &r; int &f() { return r; } };
+
+// CHECK-LABEL: define {{.*}}@_Z3fn2Ri(
+int &fn2(int &v) {
+ // CHECK: %[[INITLIST2:.*]] = alloca %struct.B, align 8
+ // CHECK: %[[R:.*]] = getelementptr inbounds %struct.B, %struct.B* %[[INITLIST2:.*]], i32 0, i32 0
+ // CHECK: store i32* %{{.*}}, i32** %[[R]], align 8
+ // CHECK: call dereferenceable({{[0-9]+}}) i32* @_ZN1B1fEv(%struct.B* %[[INITLIST2:.*]])
+ return B{v}.f();
+}
+
+// CHECK-LABEL: define {{.*}}@__cxx_global_var_init(
+//
+// CHECK: call {{.*}}@_ZN14NonTrivialInit1AC1Ev(
+// CHECK: getelementptr inbounds {{.*}}, i64 1
+// CHECK: br i1
+//
+// CHECK: getelementptr inbounds {{.*}}, i64 1
+// CHECK: icmp eq {{.*}}, i64 30
+// CHECK: br i1
+//
+// CHECK: call i32 @__cxa_atexit(
+namespace NonTrivialInit {
+ struct A { A(); A(const A&) = delete; ~A(); };
+ struct B { A a[20]; };
+ // NB, this must be large enough to be worth memsetting for this test to be
+ // meaningful.
+ B b[30] = {};
+}
+
+namespace ZeroInit {
+ enum { Zero, One };
+ constexpr int zero() { return 0; }
+ constexpr int *null() { return nullptr; }
+ struct Filler {
+ int x;
+ Filler();
+ };
+ struct S1 {
+ int x;
+ };
+
+ // These declarations, if implemented elementwise, require huge
+ // amout of memory and compiler time.
+ unsigned char data_1[1024 * 1024 * 1024 * 2u] = { 0 };
+ unsigned char data_2[1024 * 1024 * 1024 * 2u] = { Zero };
+ unsigned char data_3[1024][1024][1024] = {{{0}}};
+ unsigned char data_4[1024 * 1024 * 1024 * 2u] = { zero() };
+ int *data_5[1024 * 1024 * 512] = { nullptr };
+ int *data_6[1024 * 1024 * 512] = { null() };
+ struct S1 data_7[1024 * 1024 * 512] = {{0}};
+ char data_8[1000 * 1000 * 1000] = {};
+ int (&&data_9)[1000 * 1000 * 1000] = {0};
+ unsigned char data_10[1024 * 1024 * 1024 * 2u] = { 1 };
+ unsigned char data_11[1024 * 1024 * 1024 * 2u] = { One };
+ unsigned char data_12[1024][1024][1024] = {{{1}}};
+
+ // This variable must be initialized elementwise.
+ Filler data_e1[1024] = {};
+ // CHECK: getelementptr inbounds {{.*}} @_ZN8ZeroInit7data_e1E
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx11-initializer-array-new.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx11-initializer-array-new.cpp
new file mode 100644
index 0000000..6e24212
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cxx11-initializer-array-new.cpp
@@ -0,0 +1,160 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 %s -emit-llvm -o - | FileCheck %s
+
+// PR10878
+
+struct S { S(); S(int); ~S(); int n; };
+
+void *p = new S[2][3]{ { 1, 2, 3 }, { 4, 5, 6 } };
+
+// CHECK-LABEL: define
+// CHECK: %[[ALLOC:.*]] = call i8* @_Znam(i64 32)
+// CHECK: %[[COOKIE:.*]] = bitcast i8* %[[ALLOC]] to i64*
+// CHECK: store i64 6, i64* %[[COOKIE]]
+// CHECK: %[[START_AS_i8:.*]] = getelementptr inbounds i8, i8* %[[ALLOC]], i64 8
+// CHECK: %[[START_AS_S:.*]] = bitcast i8* %[[START_AS_i8]] to %[[S:.*]]*
+//
+// Explicit initializers:
+//
+// { 1, 2, 3 }
+//
+// CHECK: %[[S_0:.*]] = bitcast %[[S]]* %[[START_AS_S]] to [3 x %[[S]]]*
+//
+// CHECK: %[[S_0_0:.*]] = getelementptr inbounds [3 x %[[S]]], [3 x %[[S]]]* %[[S_0]], i64 0, i64 0
+// CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_0_0]], i32 1)
+// CHECK: %[[S_0_1:.*]] = getelementptr inbounds %[[S]], %[[S]]* %[[S_0_0]], i64 1
+// CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_0_1]], i32 2)
+// CHECK: %[[S_0_2:.*]] = getelementptr inbounds %[[S]], %[[S]]* %[[S_0_1]], i64 1
+// CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_0_2]], i32 3)
+//
+// { 4, 5, 6 }
+//
+// CHECK: %[[S_1:.*]] = getelementptr inbounds [3 x %[[S]]], [3 x %[[S]]]* %[[S_0]], i64 1
+//
+// CHECK: %[[S_1_0:.*]] = getelementptr inbounds [3 x %[[S]]], [3 x %[[S]]]* %[[S_1]], i64 0, i64 0
+// CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_1_0]], i32 4)
+// CHECK: %[[S_1_1:.*]] = getelementptr inbounds %[[S]], %[[S]]* %[[S_1_0]], i64 1
+// CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_1_1]], i32 5)
+// CHECK: %[[S_1_2:.*]] = getelementptr inbounds %[[S]], %[[S]]* %[[S_1_1]], i64 1
+// CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_1_2]], i32 6)
+//
+// CHECK-NOT: br i1
+// CHECK-NOT: call
+// CHECK: }
+
+int n;
+void *q = new S[n][3]{ { 1, 2, 3 }, { 4, 5, 6 } };
+
+// CHECK-LABEL: define
+//
+// CHECK: load i32, i32* @n
+// CHECK: call {{.*}} @llvm.umul.with.overflow.i64(i64 %[[N:.*]], i64 12)
+// CHECK: %[[ELTS:.*]] = mul i64 %[[N]], 3
+// CHECK: call {{.*}} @llvm.uadd.with.overflow.i64(i64 %{{.*}}, i64 8)
+// CHECK: %[[ALLOC:.*]] = call i8* @_Znam(i64 %{{.*}})
+//
+// CHECK: %[[COOKIE:.*]] = bitcast i8* %[[ALLOC]] to i64*
+// CHECK: store i64 %[[ELTS]], i64* %[[COOKIE]]
+// CHECK: %[[START_AS_i8:.*]] = getelementptr inbounds i8, i8* %[[ALLOC]], i64 8
+// CHECK: %[[START_AS_S:.*]] = bitcast i8* %[[START_AS_i8]] to %[[S]]*
+//
+// Explicit initializers:
+//
+// { 1, 2, 3 }
+//
+// CHECK: %[[S_0:.*]] = bitcast %[[S]]* %[[START_AS_S]] to [3 x %[[S]]]*
+//
+// CHECK: %[[S_0_0:.*]] = getelementptr inbounds [3 x %[[S]]], [3 x %[[S]]]* %[[S_0]], i64 0, i64 0
+// CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_0_0]], i32 1)
+// CHECK: %[[S_0_1:.*]] = getelementptr inbounds %[[S]], %[[S]]* %[[S_0_0]], i64 1
+// CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_0_1]], i32 2)
+// CHECK: %[[S_0_2:.*]] = getelementptr inbounds %[[S]], %[[S]]* %[[S_0_1]], i64 1
+// CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_0_2]], i32 3)
+//
+// { 4, 5, 6 }
+//
+// CHECK: %[[S_1:.*]] = getelementptr inbounds [3 x %[[S]]], [3 x %[[S]]]* %[[S_0]], i64 1
+//
+// CHECK: %[[S_1_0:.*]] = getelementptr inbounds [3 x %[[S]]], [3 x %[[S]]]* %[[S_1]], i64 0, i64 0
+// CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_1_0]], i32 4)
+// CHECK: %[[S_1_1:.*]] = getelementptr inbounds %[[S]], %[[S]]* %[[S_1_0]], i64 1
+// CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_1_1]], i32 5)
+// CHECK: %[[S_1_2:.*]] = getelementptr inbounds %[[S]], %[[S]]* %[[S_1_1]], i64 1
+// CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_1_2]], i32 6)
+//
+// And the rest.
+//
+// CHECK: %[[S_2:.*]] = getelementptr inbounds [3 x %[[S]]], [3 x %[[S]]]* %[[S_1]], i64 1
+// CHECK: %[[S_2_AS_S:.*]] = bitcast [3 x %[[S]]]* %[[S_2]] to %[[S]]*
+//
+// CHECK: %[[REST:.*]] = sub i64 %[[ELTS]], 6
+// CHECK: icmp eq i64 %[[REST]], 0
+// CHECK: br i1
+//
+// CHECK: %[[END:.*]] = getelementptr inbounds %[[S]], %[[S]]* %[[S_2_AS_S]], i64 %[[REST]]
+// CHECK: br label
+//
+// CHECK: %[[CUR:.*]] = phi %[[S]]* [ %[[S_2_AS_S]], {{.*}} ], [ %[[NEXT:.*]], {{.*}} ]
+// CHECK: call void @_ZN1SC1Ev(%[[S]]* %[[CUR]])
+// CHECK: %[[NEXT]] = getelementptr inbounds %[[S]], %[[S]]* %[[CUR]], i64 1
+// CHECK: icmp eq %[[S]]* %[[NEXT]], %[[END]]
+// CHECK: br i1
+//
+// CHECK: }
+
+struct T { int a; };
+void *r = new T[n][3]{ { 1, 2, 3 }, { 4, 5, 6 } };
+
+// CHECK-LABEL: define
+//
+// CHECK: load i32, i32* @n
+// CHECK: call {{.*}} @llvm.umul.with.overflow.i64(i64 %[[N:.*]], i64 12)
+// CHECK: %[[ELTS:.*]] = mul i64 %[[N]], 3
+//
+// No cookie.
+// CHECK-NOT: @llvm.uadd.with.overflow
+//
+// CHECK: %[[ALLOC:.*]] = call i8* @_Znam(i64 %{{.*}})
+//
+// CHECK: %[[START_AS_T:.*]] = bitcast i8* %[[ALLOC]] to %[[T:.*]]*
+//
+// Explicit initializers:
+//
+// { 1, 2, 3 }
+//
+// CHECK: %[[T_0:.*]] = bitcast %[[T]]* %[[START_AS_T]] to [3 x %[[T]]]*
+//
+// CHECK: %[[T_0_0:.*]] = getelementptr inbounds [3 x %[[T]]], [3 x %[[T]]]* %[[T_0]], i64 0, i64 0
+// CHECK: %[[T_0_0_0:.*]] = getelementptr inbounds %[[T]], %[[T]]* %[[T_0_0]], i32 0, i32 0
+// CHECK: store i32 1, i32* %[[T_0_0_0]]
+// CHECK: %[[T_0_1:.*]] = getelementptr inbounds %[[T]], %[[T]]* %[[T_0_0]], i64 1
+// CHECK: %[[T_0_1_0:.*]] = getelementptr inbounds %[[T]], %[[T]]* %[[T_0_1]], i32 0, i32 0
+// CHECK: store i32 2, i32* %[[T_0_1_0]]
+// CHECK: %[[T_0_2:.*]] = getelementptr inbounds %[[T]], %[[T]]* %[[T_0_1]], i64 1
+// CHECK: %[[T_0_2_0:.*]] = getelementptr inbounds %[[T]], %[[T]]* %[[T_0_2]], i32 0, i32 0
+// CHECK: store i32 3, i32* %[[T_0_2_0]]
+//
+// { 4, 5, 6 }
+//
+// CHECK: %[[T_1:.*]] = getelementptr inbounds [3 x %[[T]]], [3 x %[[T]]]* %[[T_0]], i64 1
+//
+// CHECK: %[[T_1_0:.*]] = getelementptr inbounds [3 x %[[T]]], [3 x %[[T]]]* %[[T_1]], i64 0, i64 0
+// CHECK: %[[T_1_0_0:.*]] = getelementptr inbounds %[[T]], %[[T]]* %[[T_1_0]], i32 0, i32 0
+// CHECK: store i32 4, i32* %[[T_1_0_0]]
+// CHECK: %[[T_1_1:.*]] = getelementptr inbounds %[[T]], %[[T]]* %[[T_1_0]], i64 1
+// CHECK: %[[T_1_1_0:.*]] = getelementptr inbounds %[[T]], %[[T]]* %[[T_1_1]], i32 0, i32 0
+// CHECK: store i32 5, i32* %[[T_1_1_0]]
+// CHECK: %[[T_1_2:.*]] = getelementptr inbounds %[[T]], %[[T]]* %[[T_1_1]], i64 1
+// CHECK: %[[T_1_2_0:.*]] = getelementptr inbounds %[[T]], %[[T]]* %[[T_1_2]], i32 0, i32 0
+// CHECK: store i32 6, i32* %[[T_1_2_0]]
+//
+// And the rest gets memset to 0.
+//
+// CHECK: %[[T_2:.*]] = getelementptr inbounds [3 x %[[T]]], [3 x %[[T]]]* %[[T_1]], i64 1
+// CHECK: %[[T_2_AS_T:.*]] = bitcast [3 x %[[T]]]* %[[T_2]] to %[[T]]*
+//
+// CHECK: %[[SIZE:.*]] = sub i64 %{{.*}}, 24
+// CHECK: %[[REST:.*]] = bitcast %[[T]]* %[[T_2_AS_T]] to i8*
+// CHECK: call void @llvm.memset.p0i8.i64(i8* align 4 %[[REST]], i8 0, i64 %[[SIZE]], i1 false)
+//
+// CHECK: }
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx11-noreturn.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx11-noreturn.cpp
new file mode 100644
index 0000000..58a5a37
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cxx11-noreturn.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -std=c++11 %s -o - | FileCheck %s
+
+int g();
+
+// CHECK: _Z1fv(){{.*}} [[NR:#[0-9]+]]
+[[noreturn]] int f() {
+ while (g()) {}
+}
+
+// CHECK: attributes [[NR]] = { noinline noreturn nounwind{{.*}} }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx11-special-members.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx11-special-members.cpp
new file mode 100644
index 0000000..96109ba
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cxx11-special-members.cpp
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 %s -std=c++11 -emit-llvm -o - -triple=i686-linux-gnu | FileCheck %s
+
+struct A {
+ A(const A&);
+ A &operator=(const A&);
+};
+
+struct B {
+ A a;
+ B(B&&) = default;
+ B &operator=(B&&) = default;
+};
+
+// CHECK: define {{.*}} @_Z2f1
+void f1(B &x) {
+ // CHECK-NOT: memcpy
+ // CHECK: call {{.*}} @_ZN1BC1EOS_(
+ B b(static_cast<B&&>(x));
+}
+
+// CHECK: define {{.*}} @_Z2f2
+void f2(B &x, B &y) {
+ // CHECK-NOT: memcpy
+ // CHECK: call {{.*}} @_ZN1BaSEOS_(
+ x = static_cast<B&&>(y);
+}
+
+// CHECK: define {{.*}} @_ZN1BaSEOS_(
+// CHECK: call {{.*}} @_ZN1AaSERKS_(
+
+// rdar://18309639 {
+template<int> struct C { C() = default; };
+struct D {
+ C<0> c;
+ D() { }
+};
+template struct C<0>; // was asserting
+void f3() {
+ C<0> a;
+ D b;
+}
+// Trivial default ctor, might or might not be defined, but we must not expect
+// someone else ot define it.
+// CHECK-NOT: declare {{.*}} @_ZN1CILi0EEC1Ev
+// CHECK: define {{.*}} @_ZN1DC1Ev
+
+// CHECK: define {{.*}} @_ZN1BC2EOS_(
+// CHECK: call {{.*}} @_ZN1AC1ERKS_(
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx11-thread-local-reference.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx11-thread-local-reference.cpp
new file mode 100644
index 0000000..4c1e5a7
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cxx11-thread-local-reference.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck --check-prefix=CHECK --check-prefix=LINUX %s
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple x86_64-apple-darwin12 | FileCheck --check-prefix=CHECK --check-prefix=DARWIN %s
+
+int &f();
+
+// LINUX: @r = thread_local global i32* null
+// DARWIN: @r = internal thread_local global i32* null
+thread_local int &r = f();
+
+// LINUX: @_ZTH1r = alias void (), void ()* @__tls_init
+// DARWIN: @_ZTH1r = internal alias void (), void ()* @__tls_init
+
+int &g() { return r; }
+
+// CHECK: define {{.*}} @[[R_INIT:.*]]()
+// CHECK: call dereferenceable({{[0-9]+}}) i32* @_Z1fv()
+// CHECK: store i32* %{{.*}}, i32** @r, align 8
+
+// CHECK-LABEL: define dereferenceable({{[0-9]+}}) i32* @_Z1gv()
+// LINUX: call i32* @_ZTW1r()
+// DARWIN: call cxx_fast_tlscc i32* @_ZTW1r()
+// CHECK: ret i32* %{{.*}}
+
+// LINUX: define weak_odr hidden i32* @_ZTW1r() [[ATTR0:#[0-9]+]] {
+// DARWIN: define cxx_fast_tlscc i32* @_ZTW1r() [[ATTR1:#[0-9]+]] {
+// LINUX: call void @_ZTH1r()
+// DARWIN: call cxx_fast_tlscc void @_ZTH1r()
+// CHECK: load i32*, i32** @r, align 8
+// CHECK: ret i32* %{{.*}}
+
+// LINUX-LABEL: define internal void @__tls_init()
+// DARWIN-LABEL: define internal cxx_fast_tlscc void @__tls_init()
+// CHECK: call void @[[R_INIT]]()
+
+// LINUX: attributes [[ATTR0]] = { {{.*}}"target-features"{{.*}} }
+// DARWIN: attributes [[ATTR1]] = { {{.*}}nounwind{{.*}}"target-features"{{.*}} }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx11-thread-local-visibility.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx11-thread-local-visibility.cpp
new file mode 100644
index 0000000..b46d41d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cxx11-thread-local-visibility.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck --check-prefix=LINUX %s
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple x86_64-apple-darwin12 | FileCheck --check-prefix=DARWIN %s
+
+// Regression test for PR40327
+
+// LINUX: @default_tls = thread_local global i32
+// LINUX: @hidden_tls = hidden thread_local global i32
+// LINUX: define weak_odr hidden i32* @_ZTW11default_tls()
+// LINUX: define weak_odr hidden i32* @_ZTW10hidden_tls()
+//
+// DARWIN: @default_tls = internal thread_local global i32
+// DARWIN: @hidden_tls = internal thread_local global i32
+// DARWIN: define cxx_fast_tlscc i32* @_ZTW11default_tls()
+// DARWIN: define hidden cxx_fast_tlscc i32* @_ZTW10hidden_tls()
+
+__attribute__((visibility("default"))) thread_local int default_tls;
+__attribute__((visibility("hidden"))) thread_local int hidden_tls;
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx11-thread-local.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx11-thread-local.cpp
new file mode 100644
index 0000000..de941af
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cxx11-thread-local.cpp
@@ -0,0 +1,344 @@
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck --check-prefix=CHECK --check-prefix=LINUX %s
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -O2 -disable-llvm-passes -o - -triple x86_64-linux-gnu | FileCheck --check-prefix=CHECK --check-prefix=LINUX --check-prefix=CHECK-OPT %s
+// RUN: %clang_cc1 -std=c++11 -femulated-tls -emit-llvm %s -o - \
+// RUN: -triple x86_64-linux-gnu 2>&1 | FileCheck --check-prefix=CHECK --check-prefix=LINUX %s
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple x86_64-apple-darwin12 | FileCheck --check-prefix=CHECK --check-prefix=DARWIN %s
+
+int f();
+int g();
+
+// LINUX-DAG: @a = thread_local global i32 0
+// DARWIN-DAG: @a = internal thread_local global i32 0
+thread_local int a = f();
+extern thread_local int b;
+// CHECK-DAG: @c = global i32 0
+int c = b;
+// CHECK-DAG: @_ZL1d = internal thread_local global i32 0
+static thread_local int d = g();
+
+struct U { static thread_local int m; };
+// LINUX-DAG: @_ZN1U1mE = thread_local global i32 0
+// DARWIN-DAG: @_ZN1U1mE = internal thread_local global i32 0
+thread_local int U::m = f();
+
+namespace MismatchedInitType {
+ // Check that we don't crash here when we're forced to create a new global
+ // variable (with a different type) when we add the initializer.
+ union U {
+ int a;
+ float f;
+ constexpr U() : f(0.0) {}
+ };
+ static thread_local U u;
+ void *p = &u;
+}
+
+template<typename T> struct V { static thread_local int m; };
+template<typename T> thread_local int V<T>::m = g();
+
+template<typename T> struct W { static thread_local int m; };
+template<typename T> thread_local int W<T>::m = 123;
+
+struct Dtor { ~Dtor(); };
+template<typename T> struct X { static thread_local Dtor m; };
+template<typename T> thread_local Dtor X<T>::m;
+
+// CHECK-DAG: @e = global
+void *e = V<int>::m + W<int>::m + &X<int>::m;
+
+template thread_local int V<float>::m;
+template thread_local int W<float>::m;
+template thread_local Dtor X<float>::m;
+
+extern template thread_local int V<char>::m;
+extern template thread_local int W<char>::m;
+extern template thread_local Dtor X<char>::m;
+
+void *e2 = V<char>::m + W<char>::m + &X<char>::m;
+
+// CHECK-DAG: @_ZN1VIiE1mE = linkonce_odr thread_local global i32 0
+// CHECK-DAG: @_ZN1WIiE1mE = linkonce_odr thread_local global i32 123
+// CHECK-DAG: @_ZN1XIiE1mE = linkonce_odr thread_local global {{.*}}
+// CHECK-DAG: @_ZN1VIfE1mE = weak_odr thread_local global i32 0
+// CHECK-DAG: @_ZN1WIfE1mE = weak_odr thread_local global i32 123
+// CHECK-DAG: @_ZN1XIfE1mE = weak_odr thread_local global {{.*}}
+
+// CHECK-DAG: @_ZZ1fvE1n = internal thread_local global i32 0
+
+// CHECK-DAG: @_ZGVZ1fvE1n = internal thread_local global i8 0
+
+// CHECK-DAG: @_ZZ8tls_dtorvE1s = internal thread_local global
+// CHECK-DAG: @_ZGVZ8tls_dtorvE1s = internal thread_local global i8 0
+
+// CHECK-DAG: @_ZZ8tls_dtorvE1t = internal thread_local global
+// CHECK-DAG: @_ZGVZ8tls_dtorvE1t = internal thread_local global i8 0
+
+// CHECK-DAG: @_ZZ8tls_dtorvE1u = internal thread_local global
+// CHECK-DAG: @_ZGVZ8tls_dtorvE1u = internal thread_local global i8 0
+// CHECK-DAG: @_ZGRZ8tls_dtorvE1u_ = internal thread_local global
+
+// CHECK-DAG: @_ZGVN1VIiE1mE = linkonce_odr thread_local global i64 0
+
+// CHECK-DAG: @__tls_guard = internal thread_local global i8 0
+
+// CHECK-DAG: @llvm.global_ctors = appending global {{.*}} @[[GLOBAL_INIT:[^ ]*]]
+
+// LINUX-DAG: @_ZTH1a = alias void (), void ()* @__tls_init
+// DARWIN-DAG: @_ZTH1a = internal alias void (), void ()* @__tls_init
+// CHECK-DAG: @_ZTHL1d = internal alias void (), void ()* @__tls_init
+// LINUX-DAG: @_ZTHN1U1mE = alias void (), void ()* @__tls_init
+// DARWIN-DAG: @_ZTHN1U1mE = internal alias void (), void ()* @__tls_init
+// CHECK-DAG: @_ZTHN1VIiE1mE = linkonce_odr alias void (), void ()* @[[V_M_INIT:[^, ]*]]
+// CHECK-NOT: @_ZTHN1WIiE1mE =
+// CHECK-DAG: @_ZTHN1XIiE1mE = linkonce_odr alias void (), void ()* @[[X_M_INIT:[^, ]*]]
+// CHECK-DAG: @_ZTHN1VIfE1mE = weak_odr alias void (), void ()* @[[VF_M_INIT:[^, ]*]]
+// CHECK-NOT: @_ZTHN1WIfE1mE =
+// CHECK-DAG: @_ZTHN1XIfE1mE = weak_odr alias void (), void ()* @[[XF_M_INIT:[^, ]*]]
+
+
+// Individual variable initialization functions:
+
+// CHECK: define {{.*}} @[[A_INIT:.*]]()
+// CHECK: call i32 @_Z1fv()
+// CHECK-NEXT: store i32 {{.*}}, i32* @a, align 4
+
+// CHECK-LABEL: define i32 @_Z1fv()
+int f() {
+ // CHECK: %[[GUARD:.*]] = load i8, i8* @_ZGVZ1fvE1n, align 1
+ // CHECK: %[[NEED_INIT:.*]] = icmp eq i8 %[[GUARD]], 0
+ // CHECK: br i1 %[[NEED_INIT]]
+
+ // CHECK: %[[CALL:.*]] = call i32 @_Z1gv()
+ // CHECK: store i32 %[[CALL]], i32* @_ZZ1fvE1n, align 4
+ // CHECK: store i8 1, i8* @_ZGVZ1fvE1n
+ // CHECK: br label
+ static thread_local int n = g();
+
+ // CHECK: load i32, i32* @_ZZ1fvE1n, align 4
+ return n;
+}
+
+// CHECK: define {{.*}} @[[C_INIT:.*]]()
+// LINUX: call i32* @_ZTW1b()
+// DARWIN: call cxx_fast_tlscc i32* @_ZTW1b()
+// CHECK-NEXT: load i32, i32* %{{.*}}, align 4
+// CHECK-NEXT: store i32 %{{.*}}, i32* @c, align 4
+
+// LINUX-LABEL: define weak_odr hidden i32* @_ZTW1b()
+// LINUX: br i1 icmp ne (void ()* @_ZTH1b, void ()* null),
+// not null:
+// LINUX: call void @_ZTH1b()
+// LINUX: br label
+// finally:
+// LINUX: ret i32* @b
+// DARWIN-LABEL: declare cxx_fast_tlscc i32* @_ZTW1b()
+// There is no definition of the thread wrapper on Darwin for external TLV.
+
+// CHECK: define {{.*}} @[[D_INIT:.*]]()
+// CHECK: call i32 @_Z1gv()
+// CHECK-NEXT: store i32 %{{.*}}, i32* @_ZL1d, align 4
+
+// CHECK: define {{.*}} @[[U_M_INIT:.*]]()
+// CHECK: call i32 @_Z1fv()
+// CHECK-NEXT: store i32 %{{.*}}, i32* @_ZN1U1mE, align 4
+
+// CHECK: define {{.*}} @[[E_INIT:.*]]()
+// LINUX: call i32* @_ZTWN1VIiE1mE()
+// DARWIN: call cxx_fast_tlscc i32* @_ZTWN1VIiE1mE()
+// CHECK-NEXT: load i32, i32* %{{.*}}, align 4
+// LINUX: call {{.*}}* @_ZTWN1XIiE1mE()
+// DARWIN: call cxx_fast_tlscc {{.*}}* @_ZTWN1XIiE1mE()
+// CHECK: store {{.*}} @e
+
+// LINUX-LABEL: define weak_odr hidden i32* @_ZTWN1VIiE1mE()
+// DARWIN-LABEL: define weak_odr hidden cxx_fast_tlscc i32* @_ZTWN1VIiE1mE()
+// LINUX: call void @_ZTHN1VIiE1mE()
+// DARWIN: call cxx_fast_tlscc void @_ZTHN1VIiE1mE()
+// CHECK: ret i32* @_ZN1VIiE1mE
+
+// LINUX-LABEL: define weak_odr hidden i32* @_ZTWN1WIiE1mE()
+// DARWIN-LABEL: define weak_odr hidden cxx_fast_tlscc i32* @_ZTWN1WIiE1mE()
+// CHECK-NOT: call
+// CHECK: ret i32* @_ZN1WIiE1mE
+
+// LINUX-LABEL: define weak_odr hidden {{.*}}* @_ZTWN1XIiE1mE()
+// DARWIN-LABEL: define weak_odr hidden cxx_fast_tlscc {{.*}}* @_ZTWN1XIiE1mE()
+// LINUX: call void @_ZTHN1XIiE1mE()
+// DARWIN: call cxx_fast_tlscc void @_ZTHN1XIiE1mE()
+// CHECK: ret {{.*}}* @_ZN1XIiE1mE
+
+// LINUX: define internal void @[[VF_M_INIT]]()
+// DARWIN: define internal cxx_fast_tlscc void @[[VF_M_INIT]]()
+// LINUX-SAME: comdat($_ZN1VIfE1mE)
+// DARWIN-NOT: comdat
+// CHECK: load i8, i8* bitcast (i64* @_ZGVN1VIfE1mE to i8*)
+// CHECK: %[[VF_M_INITIALIZED:.*]] = icmp eq i8 %{{.*}}, 0
+// CHECK: br i1 %[[VF_M_INITIALIZED]],
+// need init:
+// CHECK: call i32 @_Z1gv()
+// CHECK: store i32 %{{.*}}, i32* @_ZN1VIfE1mE, align 4
+// CHECK: store i64 1, i64* @_ZGVN1VIfE1mE
+// CHECK: br label
+
+// LINUX: define internal void @[[XF_M_INIT]]()
+// DARWIN: define internal cxx_fast_tlscc void @[[XF_M_INIT]]()
+// LINUX-SAME: comdat($_ZN1XIfE1mE)
+// DARWIN-NOT: comdat
+// CHECK: load i8, i8* bitcast (i64* @_ZGVN1XIfE1mE to i8*)
+// CHECK: %[[XF_M_INITIALIZED:.*]] = icmp eq i8 %{{.*}}, 0
+// CHECK: br i1 %[[XF_M_INITIALIZED]],
+// need init:
+// LINUX: call {{.*}}__cxa_thread_atexit
+// DARWIN: call {{.*}}_tlv_atexit
+// CHECK: store i64 1, i64* @_ZGVN1XIfE1mE
+// CHECK: br label
+
+// LINUX: declare i32 @__cxa_thread_atexit(void (i8*)*, i8*, i8*)
+// DARWIN: declare i32 @_tlv_atexit(void (i8*)*, i8*, i8*)
+
+// DARWIN: declare cxx_fast_tlscc i32* @_ZTWN1VIcE1mE()
+// LINUX: define weak_odr hidden i32* @_ZTWN1VIcE1mE()
+// LINUX-NOT: comdat
+// LINUX: br i1 icmp ne (void ()* @_ZTHN1VIcE1mE,
+// LINUX: call void @_ZTHN1VIcE1mE()
+// LINUX: ret i32* @_ZN1VIcE1mE
+
+// DARWIN: declare cxx_fast_tlscc i32* @_ZTWN1WIcE1mE()
+// LINUX: define weak_odr hidden i32* @_ZTWN1WIcE1mE()
+// LINUX-NOT: comdat
+// LINUX: br i1 icmp ne (void ()* @_ZTHN1WIcE1mE,
+// LINUX: call void @_ZTHN1WIcE1mE()
+// LINUX: ret i32* @_ZN1WIcE1mE
+
+// DARWIN: declare cxx_fast_tlscc {{.*}}* @_ZTWN1XIcE1mE()
+// LINUX: define weak_odr hidden {{.*}}* @_ZTWN1XIcE1mE()
+// LINUX-NOT: comdat
+// LINUX: br i1 icmp ne (void ()* @_ZTHN1XIcE1mE,
+// LINUX: call void @_ZTHN1XIcE1mE()
+// LINUX: ret {{.*}}* @_ZN1XIcE1mE
+
+struct S { S(); ~S(); };
+struct T { ~T(); };
+
+// CHECK-LABEL: define void @_Z8tls_dtorv()
+void tls_dtor() {
+ // CHECK: load i8, i8* @_ZGVZ8tls_dtorvE1s
+ // CHECK: call void @_ZN1SC1Ev(%struct.S* @_ZZ8tls_dtorvE1s)
+ // LINUX: call i32 @__cxa_thread_atexit({{.*}}@_ZN1SD1Ev {{.*}} @_ZZ8tls_dtorvE1s{{.*}} @__dso_handle
+ // DARWIN: call i32 @_tlv_atexit({{.*}}@_ZN1SD1Ev {{.*}} @_ZZ8tls_dtorvE1s{{.*}} @__dso_handle
+ // CHECK: store i8 1, i8* @_ZGVZ8tls_dtorvE1s
+ static thread_local S s;
+
+ // CHECK: load i8, i8* @_ZGVZ8tls_dtorvE1t
+ // CHECK-NOT: _ZN1T
+ // LINUX: call i32 @__cxa_thread_atexit({{.*}}@_ZN1TD1Ev {{.*}}@_ZZ8tls_dtorvE1t{{.*}} @__dso_handle
+ // DARWIN: call i32 @_tlv_atexit({{.*}}@_ZN1TD1Ev {{.*}}@_ZZ8tls_dtorvE1t{{.*}} @__dso_handle
+ // CHECK: store i8 1, i8* @_ZGVZ8tls_dtorvE1t
+ static thread_local T t;
+
+ // CHECK: load i8, i8* @_ZGVZ8tls_dtorvE1u
+ // CHECK: call void @_ZN1SC1Ev(%struct.S* @_ZGRZ8tls_dtorvE1u_)
+ // LINUX: call i32 @__cxa_thread_atexit({{.*}}@_ZN1SD1Ev {{.*}} @_ZGRZ8tls_dtorvE1u_{{.*}} @__dso_handle
+ // DARWIN: call i32 @_tlv_atexit({{.*}}@_ZN1SD1Ev {{.*}} @_ZGRZ8tls_dtorvE1u_{{.*}} @__dso_handle
+ // CHECK: store i8 1, i8* @_ZGVZ8tls_dtorvE1u
+ static thread_local const S &u = S();
+}
+
+// CHECK: define {{.*}} @_Z7PR15991v(
+int PR15991() {
+ thread_local int n;
+ auto l = [] { return n; };
+ return l();
+}
+
+struct PR19254 {
+ static thread_local int n;
+ int f();
+};
+// CHECK: define {{.*}} @_ZN7PR192541fEv(
+int PR19254::f() {
+ // LINUX: call void @_ZTHN7PR192541nE(
+ // DARWIN: call cxx_fast_tlscc i32* @_ZTWN7PR192541nE(
+ return this->n;
+}
+
+namespace {
+thread_local int anon_i{1};
+}
+void set_anon_i() {
+ anon_i = 2;
+}
+// LINUX-LABEL: define internal i32* @_ZTWN12_GLOBAL__N_16anon_iE()
+// DARWIN-LABEL: define internal cxx_fast_tlscc i32* @_ZTWN12_GLOBAL__N_16anon_iE()
+
+// LINUX: define internal void @[[V_M_INIT]]()
+// DARWIN: define internal cxx_fast_tlscc void @[[V_M_INIT]]()
+// LINUX-SAME: comdat($_ZN1VIiE1mE)
+// DARWIN-NOT: comdat
+// CHECK: load i8, i8* bitcast (i64* @_ZGVN1VIiE1mE to i8*)
+// CHECK: %[[V_M_INITIALIZED:.*]] = icmp eq i8 %{{.*}}, 0
+// CHECK: br i1 %[[V_M_INITIALIZED]],
+// need init:
+// CHECK: call i32 @_Z1gv()
+// CHECK: store i32 %{{.*}}, i32* @_ZN1VIiE1mE, align 4
+// CHECK: store i64 1, i64* @_ZGVN1VIiE1mE
+// CHECK: br label
+
+// LINUX: define internal void @[[X_M_INIT]]()
+// DARWIN: define internal cxx_fast_tlscc void @[[X_M_INIT]]()
+// LINUX-SAME: comdat($_ZN1XIiE1mE)
+// DARWIN-NOT: comdat
+// CHECK: load i8, i8* bitcast (i64* @_ZGVN1XIiE1mE to i8*)
+// CHECK: %[[X_M_INITIALIZED:.*]] = icmp eq i8 %{{.*}}, 0
+// CHECK: br i1 %[[X_M_INITIALIZED]],
+// need init:
+// LINUX: call {{.*}}__cxa_thread_atexit
+// DARWIN: call {{.*}}_tlv_atexit
+// CHECK: store i64 1, i64* @_ZGVN1XIiE1mE
+// CHECK: br label
+
+// CHECK: define {{.*}}@[[GLOBAL_INIT:.*]]()
+// CHECK: call void @[[C_INIT]]()
+// CHECK: call void @[[E_INIT]]()
+
+
+// CHECK: define {{.*}}@__tls_init()
+// CHECK: load i8, i8* @__tls_guard
+// CHECK: %[[NEED_TLS_INIT:.*]] = icmp eq i8 %{{.*}}, 0
+// CHECK: br i1 %[[NEED_TLS_INIT]],
+// init:
+// CHECK: store i8 1, i8* @__tls_guard
+// CHECK-OPT: call {}* @llvm.invariant.start.p0i8(i64 1, i8* @__tls_guard)
+// CHECK-NOT: call void @[[V_M_INIT]]()
+// CHECK: call void @[[A_INIT]]()
+// CHECK-NOT: call void @[[V_M_INIT]]()
+// CHECK: call void @[[D_INIT]]()
+// CHECK-NOT: call void @[[V_M_INIT]]()
+// CHECK: call void @[[U_M_INIT]]()
+// CHECK-NOT: call void @[[V_M_INIT]]()
+
+
+// LINUX: define weak_odr hidden i32* @_ZTW1a()
+// DARWIN: define cxx_fast_tlscc i32* @_ZTW1a()
+// LINUX: call void @_ZTH1a()
+// DARWIN: call cxx_fast_tlscc void @_ZTH1a()
+// CHECK: ret i32* @a
+// CHECK: }
+
+
+// LINUX: declare extern_weak void @_ZTH1b() [[ATTR:#[0-9]+]]
+
+
+// LINUX-LABEL: define internal i32* @_ZTWL1d()
+// DARWIN-LABEL: define internal cxx_fast_tlscc i32* @_ZTWL1d()
+// LINUX: call void @_ZTHL1d()
+// DARWIN: call cxx_fast_tlscc void @_ZTHL1d()
+// CHECK: ret i32* @_ZL1d
+
+// LINUX-LABEL: define weak_odr hidden i32* @_ZTWN1U1mE()
+// DARWIN-LABEL: define cxx_fast_tlscc i32* @_ZTWN1U1mE()
+// LINUX: call void @_ZTHN1U1mE()
+// DARWIN: call cxx_fast_tlscc void @_ZTHN1U1mE()
+// CHECK: ret i32* @_ZN1U1mE
+
+// LINUX: attributes [[ATTR]] = { {{.+}} }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx11-trivial-initializer-struct.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx11-trivial-initializer-struct.cpp
new file mode 100644
index 0000000..cded6da
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cxx11-trivial-initializer-struct.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -std=c++11 -S -emit-llvm -o %t-c++11.ll %s -triple x86_64-apple-darwin10
+// RUN: FileCheck %s < %t-c++11.ll
+// RUN: %clang_cc1 -std=c++98 -S -emit-llvm -o %t.ll %s -triple x86_64-apple-darwin10
+// RUN: diff %t.ll %t-c++11.ll
+
+// rdar://12897704
+
+struct sAFSearchPos {
+ unsigned char *pos;
+ unsigned char count;
+};
+
+static volatile struct sAFSearchPos testPositions;
+// CHECK: @_ZL13testPositions = internal global %struct.sAFSearchPos zeroinitializer
+
+static volatile struct sAFSearchPos arrayPositions[100][10][5];
+// CHECK: @_ZL14arrayPositions = internal global [100 x [10 x [5 x %struct.sAFSearchPos]]] zeroinitializer
+
+int main() {
+ return testPositions.count + arrayPositions[10][4][3].count;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx11-unrestricted-union.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx11-unrestricted-union.cpp
new file mode 100644
index 0000000..2f22ad2
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cxx11-unrestricted-union.cpp
@@ -0,0 +1,76 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++11 -emit-llvm %s -o - | FileCheck %s
+
+struct A {
+ A(); A(const A&); A(A&&); A &operator=(const A&); A &operator=(A&&); ~A();
+};
+struct B {
+ B(); B(const B&); B(B&&); B &operator=(const B&); B &operator=(B&&); ~B();
+};
+
+union U {
+ U();
+ U(const U &);
+ U(U &&);
+ U &operator=(const U&);
+ U &operator=(U&&);
+ ~U();
+
+ A a;
+ int n;
+};
+
+// CHECK-NOT: _ZN1A
+U::U() {}
+U::U(const U&) {}
+U::U(U&&) {}
+U &U::operator=(const U&) { return *this; }
+U &U::operator=(U &&) { return *this; }
+U::~U() {}
+
+struct S {
+ S();
+ S(const S &);
+ S(S &&);
+ S &operator=(const S&);
+ S &operator=(S&&);
+ ~S();
+
+ union {
+ A a;
+ int n;
+ };
+ B b;
+ int m;
+};
+
+// CHECK: _ZN1SC2Ev
+// CHECK-NOT: _ZN1A
+// CHECK: _ZN1BC1Ev
+S::S() {}
+
+// CHECK-NOT: _ZN1A
+
+// CHECK: _ZN1SC2ERKS_
+// CHECK-NOT: _ZN1A
+// CHECK: _ZN1BC1Ev
+S::S(const S&) {}
+
+// CHECK-NOT: _ZN1A
+
+// CHECK: _ZN1SC2EOS_
+// CHECK-NOT: _ZN1A
+// CHECK: _ZN1BC1Ev
+S::S(S&&) {}
+
+// CHECK-NOT: _ZN1A
+// CHECK-NOT: _ZN1B
+S &S::operator=(const S&) { return *this; }
+
+S &S::operator=(S &&) { return *this; }
+
+// CHECK: _ZN1SD2Ev
+// CHECK-NOT: _ZN1A
+// CHECK: _ZN1BD1Ev
+S::~S() {}
+
+// CHECK-NOT: _ZN1A
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx11-user-defined-literal.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx11-user-defined-literal.cpp
new file mode 100644
index 0000000..05c04b1
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cxx11-user-defined-literal.cpp
@@ -0,0 +1,69 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s
+
+struct S { S(); ~S(); S(const S &); void operator()(int); };
+using size_t = decltype(sizeof(int));
+S operator"" _x(const char *, size_t);
+S operator"" _y(wchar_t);
+S operator"" _z(unsigned long long);
+S operator"" _f(long double);
+S operator"" _r(const char *);
+template<char...Cs> S operator"" _t() { return S(); }
+
+// CHECK: @[[s_foo:.*]] = {{.*}} constant [4 x i8] c"foo\00"
+// CHECK: @[[s_bar:.*]] = {{.*}} constant [4 x i8] c"bar\00"
+// CHECK: @[[s_123:.*]] = {{.*}} constant [4 x i8] c"123\00"
+// CHECK: @[[s_4_9:.*]] = {{.*}} constant [4 x i8] c"4.9\00"
+// CHECK: @[[s_0xffffeeee:.*]] = {{.*}} constant [11 x i8] c"0xffffeeee\00"
+
+void f() {
+ // CHECK: call void @_Zli2_xPKcm({{.*}}, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[s_foo]], i32 0, i32 0), i64 3)
+ // CHECK: call void @_Zli2_xPKcm({{.*}}, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[s_bar]], i32 0, i32 0), i64 3)
+ // CHECK: call void @_Zli2_yw({{.*}} 97)
+ // CHECK: call void @_Zli2_zy({{.*}} 42)
+ // CHECK: call void @_Zli2_fe({{.*}} x86_fp80 0xK3FFF8000000000000000)
+ // CHECK: call void @_ZN1SD1Ev({{.*}})
+ // CHECK: call void @_ZN1SD1Ev({{.*}})
+ // CHECK: call void @_ZN1SD1Ev({{.*}})
+ // CHECK: call void @_ZN1SD1Ev({{.*}})
+ // CHECK: call void @_ZN1SD1Ev({{.*}})
+ "foo"_x, "bar"_x, L'a'_y, 42_z, 1.0_f;
+
+ // CHECK: call void @_Zli2_rPKc({{.*}}, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[s_123]], i32 0, i32 0))
+ // CHECK: call void @_Zli2_rPKc({{.*}}, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[s_4_9]], i32 0, i32 0))
+ // CHECK: call void @_Zli2_rPKc({{.*}}, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @[[s_0xffffeeee]], i32 0, i32 0))
+ // CHECK: call void @_ZN1SD1Ev({{.*}})
+ // CHECK: call void @_ZN1SD1Ev({{.*}})
+ // CHECK: call void @_ZN1SD1Ev({{.*}})
+ 123_r, 4.9_r, 0xffff\
+eeee_r;
+
+ // FIXME: This mangling is insane. Maybe we should have a special case for
+ // char parameter packs?
+ // CHECK: call void @_Zli2_tIJLc48ELc120ELc49ELc50ELc51ELc52ELc53ELc54ELc55ELc56EEE1Sv({{.*}})
+ // CHECK: call void @_ZN1SD1Ev({{.*}})
+ 0x12345678_t;
+}
+
+// CHECK: define {{.*}} @_Zli2_tIJLc48ELc120ELc49ELc50ELc51ELc52ELc53ELc54ELc55ELc56EEE1Sv(
+
+template<typename T> auto g(T t) -> decltype("foo"_x(t)) { return "foo"_x(t); }
+template<typename T> auto i(T t) -> decltype(operator"" _x("foo", 3)(t)) { return operator"" _x("foo", 3)(t); }
+
+void h() {
+ g(42);
+ i(42);
+}
+
+// CHECK: define {{.*}} @_Z1hv()
+// CHECK: call void @_Z1gIiEDTclclL_Zli2_xPKcmELA4_S0_ELm3EEfp_EET_(i32 42)
+// CHECK: call void @_Z1iIiEDTclclL_Zli2_xPKcmELA4_S0_ELi3EEfp_EET_(i32 42)
+
+// CHECK: define {{.*}} @_Z1gIiEDTclclL_Zli2_xPKcmELA4_S0_ELm3EEfp_EET_(i32
+// CHECK: call void @_Zli2_xPKcm({{.*}}, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @{{.*}}, i32 0, i32 0), i64 3)
+// CHECK: call void @_ZN1SclEi
+// CHECK: call void @_ZN1SD1Ev
+
+// CHECK: define {{.*}} @_Z1iIiEDTclclL_Zli2_xPKcmELA4_S0_ELi3EEfp_EET_(i32
+// CHECK: call void @_Zli2_xPKcm({{.*}}, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @{{.*}}, i32 0, i32 0), i64 3)
+// CHECK: call void @_ZN1SclEi
+// CHECK: call void @_ZN1SD1Ev
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx11-vtable-key-function.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx11-vtable-key-function.cpp
new file mode 100644
index 0000000..a4a0002
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cxx11-vtable-key-function.cpp
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - -std=c++11 | FileCheck %s
+// PR13424
+
+namespace Test1 {
+struct X {
+ virtual ~X(); // Key function.
+ virtual void f(); // Not a key function.
+};
+
+X::~X() = default;
+
+// Verify that the vtable is emitted.
+// CHECK-DAG: @_ZTVN5Test11XE = unnamed_addr constant
+}
+
+namespace Test2 {
+struct X {
+ virtual ~X() = default; // Not a key function.
+ virtual void f(); // Key function.
+};
+
+void X::f() {}
+
+// Verify that the vtable is emitted.
+// CHECK-DAG: @_ZTVN5Test21XE = unnamed_addr constant
+}
+
+namespace Test3 {
+struct X {
+ virtual ~X() = delete; // Not a key function.
+ virtual void f(); // Key function.
+};
+
+void X::f() {}
+
+// Verify that the vtable is emitted.
+// CHECK-DAG: @_ZTVN5Test31XE = unnamed_addr constant
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx1y-deduced-return-type.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx1y-deduced-return-type.cpp
new file mode 100644
index 0000000..6d15a224
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cxx1y-deduced-return-type.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -std=c++1y -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s
+
+// CHECK: @x = global {{.*}} zeroinitializer
+
+// CHECK: define {{.*}} @_Z1fv
+inline auto f() {
+ int n = 0;
+ // CHECK: load i32
+ // CHECK: store i32
+ // CHECK: ret
+ return [=] () mutable { return ++n; };
+}
+
+auto x = f();
+
+template<typename T> auto *g(T t) { return t; }
+template<typename T> decltype(auto) h(T t) { return t; }
+
+// CHECK: define {{.*}} @_Z1zv
+void z() {
+ // CHECK: call {{.*}} @_Z1gIPZ1fvEUlvE_EPDaT_(
+ // CHECK: call {{.*}} @_Z1hIPZ1fvEUlvE_EDcT_(
+ g(&x);
+ h(&x);
+}
+
+auto i() { return [] {}; }
+// CHECK: define {{.*}} @_Z1jv
+auto j() {
+ // CHECK: call {{.*}} @"_Z1hIZ1ivE3$_0EDcT_"()
+ h(i());
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx1y-generic-lambdas.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx1y-generic-lambdas.cpp
new file mode 100644
index 0000000..9ab44cd
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cxx1y-generic-lambdas.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s -std=c++14 | FileCheck %s
+
+template<typename> struct custom_copy_ctor {
+ custom_copy_ctor() = default;
+ custom_copy_ctor(custom_copy_ctor const &) {}
+};
+
+// CHECK: define {{.*}} @_ZN16custom_copy_ctorIvEC2ERKS0_(
+void pr22354() {
+ custom_copy_ctor<void> cc;
+ [cc](auto){}(1);
+}
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx1y-init-captures.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx1y-init-captures.cpp
new file mode 100644
index 0000000..c76180c
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cxx1y-init-captures.cpp
@@ -0,0 +1,116 @@
+// RUN: %clang_cc1 -std=c++1y -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s
+
+struct S {
+ S();
+ S(S &&);
+ ~S();
+};
+
+void f() {
+ (void) [s(S{})] {};
+}
+
+// CHECK-LABEL: define void @_Z1fv(
+// CHECK: call void @_ZN1SC1Ev(
+// CHECK: call void @"_ZZ1fvEN3$_0D1Ev"(
+
+// CHECK-LABEL: define internal void @"_ZZ1fvEN3$_0D1Ev"(
+// CHECK: @"_ZZ1fvEN3$_0D2Ev"(
+
+// D2 at end of file.
+
+void g() {
+ [a(1), b(2)] { return a + b; } ();
+}
+
+// CHECK-LABEL: define void @_Z1gv(
+// CHECK: getelementptr inbounds {{.*}}, i32 0, i32 0
+// CHECK: store i32 1, i32*
+// CHECK: getelementptr inbounds {{.*}}, i32 0, i32 1
+// CHECK: store i32 2, i32*
+// CHECK: call i32 @"_ZZ1gvENK3$_1clEv"(
+
+// CHECK-LABEL: define internal i32 @"_ZZ1gvENK3$_1clEv"(
+// CHECK: getelementptr inbounds {{.*}}, i32 0, i32 0
+// CHECK: load i32, i32*
+// CHECK: getelementptr inbounds {{.*}}, i32 0, i32 1
+// CHECK: load i32, i32*
+
+// CHECK: add nsw i32
+
+// CHECK-LABEL: define void @_Z18init_capture_dtorsv
+void init_capture_dtors() {
+ // Ensure that init-captures are not treated as separate full-expressions.
+ struct HasDtor { ~HasDtor() {} };
+ void some_function_call();
+ void other_function_call();
+ // CHECK: call {{.*}}some_function_call
+ // CHECK: call {{.*}}HasDtorD
+ ([x = (HasDtor(), 0)]{}, some_function_call());
+ // CHECK: call {{.*}}other_function_call
+ other_function_call();
+}
+
+int h(int a) {
+ // CHECK-LABEL: define i32 @_Z1hi(
+ // CHECK: %[[A_ADDR:.*]] = alloca i32,
+ // CHECK: %[[OUTER:.*]] = alloca
+ // CHECK: store i32 {{.*}}, i32* %[[A_ADDR]],
+ //
+ // Initialize init-capture 'b(a)' by reference.
+ // CHECK: getelementptr inbounds {{.*}}, {{.*}}* %[[OUTER]], i32 0, i32 0
+ // CHECK: store i32* %[[A_ADDR]], i32** {{.*}},
+ //
+ // Initialize init-capture 'c(a)' by copy.
+ // CHECK: getelementptr inbounds {{.*}}, {{.*}}* %[[OUTER]], i32 0, i32 1
+ // CHECK: load i32, i32* %[[A_ADDR]],
+ // CHECK: store i32
+ //
+ // CHECK: call i32 @"_ZZ1hiENK3$_2clEv"({{.*}}* %[[OUTER]])
+ return [&b(a), c(a)] {
+ // CHECK-LABEL: define internal i32 @"_ZZ1hiENK3$_2clEv"(
+ // CHECK: %[[OUTER_ADDR:.*]] = alloca
+ // CHECK: %[[INNER:.*]] = alloca
+ // CHECK: store {{.*}}, {{.*}}** %[[OUTER_ADDR]],
+ //
+ // Capture outer 'c' by reference.
+ // CHECK: %[[OUTER:.*]] = load {{.*}}*, {{.*}}** %[[OUTER_ADDR]]
+ // CHECK: getelementptr inbounds {{.*}}, {{.*}}* %[[INNER]], i32 0, i32 0
+ // CHECK-NEXT: getelementptr inbounds {{.*}}, {{.*}}* %[[OUTER]], i32 0, i32 1
+ // CHECK-NEXT: store i32* %
+ //
+ // Capture outer 'b' by copy.
+ // CHECK: getelementptr inbounds {{.*}}, {{.*}}* %[[INNER]], i32 0, i32 1
+ // CHECK-NEXT: getelementptr inbounds {{.*}}, {{.*}}* %[[OUTER]], i32 0, i32 0
+ // CHECK-NEXT: load i32*, i32** %
+ // CHECK-NEXT: load i32, i32* %
+ // CHECK-NEXT: store i32
+ //
+ // CHECK: call i32 @"_ZZZ1hiENK3$_2clEvENKUlvE_clEv"({{.*}}* %[[INNER]])
+ return [=, &c] {
+ // CHECK-LABEL: define internal void @"_ZZ1fvEN3$_0D2Ev"(
+ // CHECK: call void @_ZN1SD1Ev(
+
+ // CHECK-LABEL: define internal i32 @"_ZZZ1hiENK3$_2clEvENKUlvE_clEv"(
+ // CHECK: %[[INNER_ADDR:.*]] = alloca
+ // CHECK: store {{.*}}, {{.*}}** %[[INNER_ADDR]],
+ // CHECK: %[[INNER:.*]] = load {{.*}}*, {{.*}}** %[[INNER_ADDR]]
+ //
+ // Load capture of 'b'
+ // CHECK: getelementptr inbounds {{.*}}, {{.*}}* %[[INNER]], i32 0, i32 1
+ // CHECK: load i32, i32* %
+ //
+ // Load capture of 'c'
+ // CHECK: getelementptr inbounds {{.*}}, {{.*}}* %[[INNER]], i32 0, i32 0
+ // CHECK: load i32*, i32** %
+ // CHECK: load i32, i32* %
+ //
+ // CHECK: add nsw i32
+ return b + c;
+ } ();
+ } ();
+}
+
+// Ensure we can emit code for init-captures in global lambdas too.
+auto global_lambda = [a = 0] () mutable { return ++a; };
+int get_incremented() { return global_lambda(); }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx1y-initializer-aggregate.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx1y-initializer-aggregate.cpp
new file mode 100644
index 0000000..6d0ae8a
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cxx1y-initializer-aggregate.cpp
@@ -0,0 +1,80 @@
+// RUN: %clang_cc1 -std=c++1y %s -triple x86_64-linux-gnu -emit-llvm -o - | FileCheck %s
+
+struct A {
+ int n = 0;
+ const char *p;
+ char k = p[n];
+ int f();
+ int x = f();
+ union {
+ char c;
+ double d = 1.0;
+ };
+};
+
+int f();
+
+union B {
+ int a;
+ int f();
+ int b = f();
+};
+
+A a { .p = "foobar" };
+A b { 4, "bazquux", .x = 42, .c = 9 };
+A c { 1, 0, 'A', f(), { 3 } };
+
+// CHECK: @[[STR_A:.*]] = {{.*}} [7 x i8] c"foobar\00"
+// CHECK: @a = global {{.*}} zeroinitializer
+
+// @b has a constant initializer
+// CHECK: @[[STR_B:.*]] = {{.*}} [8 x i8] c"bazquux\00"
+// CHECK: @b = global {{.*}} i32 4, {{.*}} @[[STR_B]], {{.*}} i8 117, i32 42, {{.*}} i8 9
+
+B x;
+B y {};
+B z { 1 };
+// CHECK: @z = global {{.*}} { i32 1 }
+
+// Brace initialization should initialize the first field even though it is
+// unnamed.
+union C {
+ struct {
+ int C::*memptr;
+ };
+};
+
+C n{};
+// CHECK: @n = global %union.C { %struct.anon { i64 -1 } }, align 8
+
+// Initialization of 'a':
+
+// CHECK: store i32 0, i32* getelementptr inbounds ({{.*}} @a, i32 0, i32 0)
+// CHECK: store i8* {{.*}} @[[STR_A]]{{.*}}, i8** getelementptr inbounds ({{.*}} @a, i32 0, i32 1)
+// CHECK: load i8*, i8** getelementptr inbounds ({{.*}} @a, i32 0, i32 1)
+// CHECK: load i32, i32* getelementptr inbounds ({{.*}} @a, i32 0, i32 0)
+// CHECK: getelementptr inbounds i8, i8* %{{.*}}, {{.*}} %{{.*}}
+// CHECK: store i8 %{{.*}}, i8* getelementptr inbounds ({{.*}} @a, i32 0, i32 2)
+// CHECK: call i32 @_ZN1A1fEv({{.*}} @a)
+// CHECK: store i32 %{{.*}}, i32* getelementptr inbounds ({{.*}}, {{.*}}* @a, i32 0, i32 3)
+// CHECK: store double 1.000000e+00, double* getelementptr inbounds ({{.*}} @a, i32 0, i32 4, i32 0)
+
+// No dynamic initialization of 'b':
+
+// CHECK-NOT: @b
+
+// Initialization of 'c':
+
+// CHECK: store i32 1, i32* getelementptr inbounds ({{.*}} @c, i32 0, i32 0)
+// CHECK: store i8* null, i8** getelementptr inbounds ({{.*}} @c, i32 0, i32 1)
+// CHECK-NOT: load
+// CHECK: store i8 65, i8* getelementptr inbounds ({{.*}} @c, i32 0, i32 2)
+// CHECK: call i32 @_Z1fv()
+// CHECK: store i32 %{{.*}}, i32* getelementptr inbounds ({{.*}}, {{.*}}* @c, i32 0, i32 3)
+// CHECK-NOT: C1Ev
+// CHECK: store i8 3, i8* {{.*}} @c, i32 0, i32 4)
+
+// CHECK: call void @_ZN1BC1Ev({{.*}} @x)
+
+// CHECK: call i32 @_ZN1B1fEv({{.*}} @y)
+// CHECK: store i32 %{{.*}}, i32* getelementptr inbounds ({{.*}} @y, i32 0, i32 0)
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx1y-sized-deallocation.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx1y-sized-deallocation.cpp
new file mode 100644
index 0000000..78cc713
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cxx1y-sized-deallocation.cpp
@@ -0,0 +1,114 @@
+// Check that delete exprs call the sized deallocation function if
+// -fsized-deallocation is passed in both C++11 and C++14.
+// RUN: %clang_cc1 -std=c++11 -fsized-deallocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++14 -fsized-deallocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s
+
+// Check that we don't used sized deallocation without -fsized-deallocation and
+// C++14.
+// RUN: %clang_cc1 -std=c++11 %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefix=CHECK-UNSIZED
+// RUN: %clang_cc1 -std=c++14 %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefix=CHECK-UNSIZED
+
+// CHECK-UNSIZED-NOT: _ZdlPvm
+// CHECK-UNSIZED-NOT: _ZdaPvm
+
+typedef decltype(sizeof(0)) size_t;
+
+typedef int A;
+struct B { int n; };
+struct C { ~C() {} };
+struct D { D(); virtual ~D() {} };
+struct E {
+ void *operator new(size_t);
+ void *operator new[](size_t);
+ void operator delete(void *) noexcept;
+ void operator delete[](void *) noexcept;
+};
+struct F {
+ void *operator new(size_t);
+ void *operator new[](size_t);
+ void operator delete(void *, size_t) noexcept;
+ void operator delete[](void *, size_t) noexcept;
+};
+
+template<typename T> T get();
+
+template<typename T>
+void del() {
+ ::delete get<T*>();
+ ::delete[] get<T*>();
+ delete get<T*>();
+ delete[] get<T*>();
+}
+
+template void del<A>();
+template void del<B>();
+template void del<C>();
+template void del<D>();
+template void del<E>();
+template void del<F>();
+
+D::D() {}
+
+// CHECK-LABEL: define weak_odr void @_Z3delIiEvv()
+// CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 4)
+// CHECK: call void @_ZdaPv(i8* %{{[^ ]*}})
+//
+// CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 4)
+// CHECK: call void @_ZdaPv(i8* %{{[^ ]*}})
+
+// CHECK-LABEL: declare void @_ZdlPvm(i8*
+
+// CHECK-LABEL: define weak_odr void @_Z3delI1BEvv()
+// CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 4)
+// CHECK: call void @_ZdaPv(i8* %{{[^ ]*}})
+//
+// CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 4)
+// CHECK: call void @_ZdaPv(i8* %{{[^ ]*}})
+
+// CHECK-LABEL: define weak_odr void @_Z3delI1CEvv()
+// CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 1)
+// CHECK: mul i64 1, %{{[^ ]*}}
+// CHECK: add i64 %{{[^ ]*}}, 8
+// CHECK: call void @_ZdaPvm(i8* %{{[^ ]*}}, i64 %{{[^ ]*}})
+//
+// CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 1)
+// CHECK: mul i64 1, %{{[^ ]*}}
+// CHECK: add i64 %{{[^ ]*}}, 8
+// CHECK: call void @_ZdaPvm(i8* %{{[^ ]*}}, i64 %{{[^ ]*}})
+
+// CHECK-LABEL: declare void @_ZdaPvm(i8*
+
+// CHECK-LABEL: define weak_odr void @_Z3delI1DEvv()
+// CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 8)
+// CHECK: mul i64 8, %{{[^ ]*}}
+// CHECK: add i64 %{{[^ ]*}}, 8
+// CHECK: call void @_ZdaPvm(i8* %{{[^ ]*}}, i64 %{{[^ ]*}})
+//
+// CHECK-NOT: Zdl
+// CHECK: call void %{{.*}}
+// CHECK-NOT: Zdl
+// CHECK: mul i64 8, %{{[^ ]*}}
+// CHECK: add i64 %{{[^ ]*}}, 8
+// CHECK: call void @_ZdaPvm(i8* %{{[^ ]*}}, i64 %{{[^ ]*}})
+
+// CHECK-LABEL: define weak_odr void @_Z3delI1EEvv()
+// CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 1)
+// CHECK: call void @_ZdaPv(i8* %{{[^ ]*}})
+//
+// CHECK: call void @_ZN1EdlEPv(i8* %{{[^ ]*}})
+// CHECK: call void @_ZN1EdaEPv(i8* %{{[^ ]*}})
+
+// CHECK-LABEL: define weak_odr void @_Z3delI1FEvv()
+// CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 1)
+// CHECK: mul i64 1, %{{[^ ]*}}
+// CHECK: add i64 %{{[^ ]*}}, 8
+// CHECK: call void @_ZdaPvm(i8* %{{[^ ]*}}, i64 %{{[^ ]*}})
+//
+// CHECK: call void @_ZN1FdlEPvm(i8* %{{[^ ]*}}, i64 1)
+// CHECK: mul i64 1, %{{[^ ]*}}
+// CHECK: add i64 %{{[^ ]*}}, 8
+// CHECK: call void @_ZN1FdaEPvm(i8* %{{[^ ]*}}, i64 %{{[^ ]*}})
+
+
+// CHECK-LABEL: define linkonce_odr void @_ZN1DD0Ev(%{{[^ ]*}}* %this)
+// CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 8)
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx1y-variable-template-linkage.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx1y-variable-template-linkage.cpp
new file mode 100644
index 0000000..bc77556
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cxx1y-variable-template-linkage.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -std=c++1y -O1 -disable-llvm-passes %s -o - | FileCheck %s -check-prefix=CHECKA -check-prefix=CHECK
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -std=c++1y -O1 -disable-llvm-passes -fcxx-exceptions %s -o - | FileCheck %s -check-prefix=CHECKB -check-prefix=CHECK
+// expected-no-diagnostics
+
+// The variable template specialization x<Foo> generated in each file
+// should be 'internal global' and not 'linkonce_odr global'.
+
+template <typename T> int x = 42;
+
+// CHECK-DAG: @_Z1xIZL3foovE3FooE = internal global
+
+// CHECK-DAG: define internal dereferenceable(4) i32* @_ZL3foov(
+static int &foo() {
+ struct Foo { };
+
+ // CHECK-DAG: ret i32* @_Z1xIZL3foovE3FooE
+ return x<Foo>;
+}
+
+
+#if !__has_feature(cxx_exceptions) // File A
+// CHECKA-DAG: define dereferenceable(4) i32* @_Z3barv(
+int &bar() {
+ // CHECKA-DAG: call dereferenceable(4) i32* @_ZL3foov()
+ return foo();
+}
+
+#else // File B
+
+// CHECKB-DAG: declare dereferenceable(4) i32* @_Z3barv(
+int &bar();
+
+int main() {
+ // CHECKB-DAG: call dereferenceable(4) i32* @_Z3barv()
+ // CHECKB-DAG: call dereferenceable(4) i32* @_ZL3foov()
+ &bar() == &foo() ? throw 0 : (void)0; // Should not throw exception at runtime.
+}
+
+#endif // end of Files A and B
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx1y-variable-template.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx1y-variable-template.cpp
new file mode 100644
index 0000000..dd8f28e
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cxx1y-variable-template.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -std=c++1y -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s
+
+// Check that we keep the 'extern' when we instantiate the definition of this
+// variable template specialization.
+template<typename T> extern const int extern_redecl;
+template<typename T> const int extern_redecl = 5;
+template const int extern_redecl<int>;
+
+// CHECK: @_Z13extern_redeclIiE = weak_odr constant
+
+template<typename T> struct Outer {
+ template<typename U> struct Inner {
+ template<typename V> static int arr[];
+ };
+};
+Outer<char[100]> outer_int;
+int init_arr();
+template<typename T> template<typename U> template<typename V> int Outer<T>::Inner<U>::arr[sizeof(T) + sizeof(U) + sizeof(V)] = { init_arr() };
+int *p = Outer<char[100]>::Inner<char[20]>::arr<char[3]>;
+
+namespace PR35456 {
+// CHECK: @_ZN7PR354561nILi0EEE = linkonce_odr global i32 0
+template<int> int n;
+int *p = &n<0>;
+}
+
+// CHECK: @_ZN5OuterIA100_cE5InnerIA20_cE3arrIA3_cEE = linkonce_odr global [123 x i32] zeroinitializer
+// CHECK: @_ZGVN5OuterIA100_cE5InnerIA20_cE3arrIA3_cEE = linkonce_odr global
+
+// CHECK: call {{.*}}@_Z8init_arrv
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx1z-aligned-allocation.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx1z-aligned-allocation.cpp
new file mode 100644
index 0000000..2e2bfc5
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cxx1z-aligned-allocation.cpp
@@ -0,0 +1,222 @@
+// Check that delete exprs call aligned (de)allocation functions if
+// -faligned-allocation is passed in both C++11 and C++14.
+// RUN: %clang_cc1 -std=c++11 -fexceptions -fsized-deallocation -faligned-allocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++14 -fexceptions -fsized-deallocation -faligned-allocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++1z -fexceptions -fsized-deallocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s
+
+// RUN: %clang_cc1 -std=c++1z -fexceptions -fsized-deallocation %s -emit-llvm -triple x86_64-windows-msvc -o - | FileCheck %s --check-prefix=CHECK-MS
+
+// Check that we don't used aligned (de)allocation without -faligned-allocation or C++1z.
+// RUN: %clang_cc1 -std=c++14 -DUNALIGNED -fexceptions %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefix=CHECK-UNALIGNED
+// RUN: %clang_cc1 -std=c++1z -DUNALIGNED -fexceptions -fno-aligned-allocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefix=CHECK-UNALIGNED
+
+// CHECK-UNALIGNED-NOT: _Znwm_St11align_val_t
+// CHECK-UNALIGNED-NOT: _Znam_St11align_val_t
+// CHECK-UNALIGNED-NOT: _ZdlPv_St11align_val_t
+// CHECK-UNALIGNED-NOT: _ZdaPv_St11align_val_t
+// CHECK-UNALIGNED-NOT: _ZdlPvm_St11align_val_t
+// CHECK-UNALIGNED-NOT: _ZdaPvm_St11align_val_t
+
+typedef decltype(sizeof(0)) size_t;
+namespace std { enum class align_val_t : size_t {}; }
+
+#define OVERALIGNED alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2)
+
+// Global new and delete.
+// ======================
+struct OVERALIGNED A { A(); int n[128]; };
+
+// CHECK-LABEL: define {{.*}} @_Z2a0v()
+// CHECK: %[[ALLOC:.*]] = call i8* @_ZnwmSt11align_val_t(i64 512, i64 32)
+// CHECK: call void @_ZdlPvSt11align_val_t(i8* %[[ALLOC]], i64 32)
+// CHECK-MS-LABEL: define {{.*}} @"?a0@@YAPEAXXZ"()
+// CHECK-MS: %[[ALLOC:.*]] = call i8* @"??2@YAPEAX_KW4align_val_t@std@@@Z"(i64 512, i64 32)
+// CHECK-MS: cleanuppad
+// CHECK-MS: call void @"??3@YAXPEAXW4align_val_t@std@@@Z"(i8* %[[ALLOC]], i64 32)
+void *a0() { return new A; }
+
+// FIXME: Why don't we call the sized array deallocation overload in this case?
+// The size is known.
+//
+// CHECK-LABEL: define {{.*}} @_Z2a1l(
+// CHECK: %[[ALLOC:.*]] = call i8* @_ZnamSt11align_val_t(i64 %{{.*}}, i64 32)
+// No array cookie.
+// CHECK-NOT: store
+// CHECK: invoke void @_ZN1AC1Ev(
+// CHECK: call void @_ZdaPvSt11align_val_t(i8* %[[ALLOC]], i64 32)
+// CHECK-MS-LABEL: define {{.*}} @"?a1@@YAPEAXJ@Z"(
+// CHECK-MS: %[[ALLOC:.*]] = call i8* @"??_U@YAPEAX_KW4align_val_t@std@@@Z"(i64 %{{.*}}, i64 32)
+// No array cookie.
+// CHECK-MS-NOT: store
+// CHECK-MS: invoke %struct.A* @"??0A@@QEAA@XZ"(
+// CHECK-MS: cleanuppad
+// CHECK-MS: call void @"??_V@YAXPEAXW4align_val_t@std@@@Z"(i8* %[[ALLOC]], i64 32)
+void *a1(long n) { return new A[n]; }
+
+// CHECK-LABEL: define {{.*}} @_Z2a2P1A(
+// CHECK: call void @_ZdlPvmSt11align_val_t(i8* %{{.*}}, i64 512, i64 32) #9
+void a2(A *p) { delete p; }
+
+// CHECK-LABEL: define {{.*}} @_Z2a3P1A(
+// CHECK: call void @_ZdaPvSt11align_val_t(i8* %{{.*}}, i64 32) #9
+void a3(A *p) { delete[] p; }
+
+
+// Class-specific usual new and delete.
+// ====================================
+struct OVERALIGNED B {
+ B();
+ // These are just a distraction. We should ignore them.
+ void *operator new(size_t);
+ void operator delete(void*, size_t);
+ void operator delete[](void*, size_t);
+
+ void *operator new(size_t, std::align_val_t);
+ void operator delete(void*, std::align_val_t);
+ void operator delete[](void*, std::align_val_t);
+
+ int n[128];
+};
+
+// CHECK-LABEL: define {{.*}} @_Z2b0v()
+// CHECK: %[[ALLOC:.*]] = call i8* @_ZN1BnwEmSt11align_val_t(i64 512, i64 32)
+// CHECK: call void @_ZN1BdlEPvSt11align_val_t(i8* %[[ALLOC]], i64 32)
+void *b0() { return new B; }
+
+// CHECK-LABEL: define {{.*}} @_Z2b1l(
+// CHECK: %[[ALLOC:.*]] = call i8* @_ZnamSt11align_val_t(i64 %{{.*}}, i64 32)
+// No array cookie.
+// CHECK-NOT: store
+// CHECK: invoke void @_ZN1BC1Ev(
+// CHECK: call void @_ZN1BdaEPvSt11align_val_t(i8* %[[ALLOC]], i64 32)
+void *b1(long n) { return new B[n]; }
+
+// CHECK-LABEL: define {{.*}} @_Z2b2P1B(
+// CHECK: call void @_ZN1BdlEPvSt11align_val_t(i8* %{{.*}}, i64 32)
+void b2(B *p) { delete p; }
+
+// CHECK-LABEL: define {{.*}} @_Z2b3P1B(
+// CHECK: call void @_ZN1BdaEPvSt11align_val_t(i8* %{{.*}}, i64 32)
+void b3(B *p) { delete[] p; }
+
+struct OVERALIGNED C {
+ C();
+ void *operator new[](size_t, std::align_val_t);
+ void operator delete[](void*, size_t, std::align_val_t);
+
+ // It doesn't matter that we have an unaligned operator delete[] that doesn't
+ // want the size. What matters is that the aligned one does.
+ void operator delete[](void*);
+};
+
+// This one has an array cookie.
+// CHECK-LABEL: define {{.*}} @_Z2b4l(
+// CHECK: call {{.*}} @llvm.umul.with.overflow{{.*}}i64 32
+// CHECK: call {{.*}} @llvm.uadd.with.overflow{{.*}}i64 32
+// CHECK: %[[ALLOC:.*]] = call i8* @_ZN1CnaEmSt11align_val_t(i64 %{{.*}}, i64 32)
+// CHECK: store
+// CHECK: call void @_ZN1CC1Ev(
+//
+// Note, we're still calling a placement allocation function, and there is no
+// matching placement operator delete. =(
+// FIXME: This seems broken.
+// CHECK-NOT: call void @_ZN1CdaEPvmSt11align_val_t(
+#ifndef UNALIGNED
+void *b4(long n) { return new C[n]; }
+#endif
+
+// CHECK-LABEL: define {{.*}} @_Z2b5P1C(
+// CHECK: mul i64{{.*}} 32
+// CHECK: add i64{{.*}} 32
+// CHECK: call void @_ZN1CdaEPvmSt11align_val_t(
+void b5(C *p) { delete[] p; }
+
+
+// Global placement new.
+// =====================
+
+struct Q { int n; } q;
+void *operator new(size_t, Q);
+void *operator new(size_t, std::align_val_t, Q);
+void operator delete(void*, Q);
+void operator delete(void*, std::align_val_t, Q);
+
+// CHECK-LABEL: define {{.*}} @_Z2c0v(
+// CHECK: %[[ALLOC:.*]] = call i8* @_ZnwmSt11align_val_t1Q(i64 512, i64 32, i32 %
+// CHECK: call void @_ZdlPvSt11align_val_t1Q(i8* %[[ALLOC]], i64 32, i32 %
+void *c0() { return new (q) A; }
+
+
+// Class-specific placement new.
+// =============================
+
+struct OVERALIGNED D {
+ D();
+ void *operator new(size_t, Q);
+ void *operator new(size_t, std::align_val_t, Q);
+ void operator delete(void*, Q);
+ void operator delete(void*, std::align_val_t, Q);
+};
+
+// CHECK-LABEL: define {{.*}} @_Z2d0v(
+// CHECK: %[[ALLOC:.*]] = call i8* @_ZN1DnwEmSt11align_val_t1Q(i64 32, i64 32, i32 %
+// CHECK: call void @_ZN1DdlEPvSt11align_val_t1Q(i8* %[[ALLOC]], i64 32, i32 %
+void *d0() { return new (q) D; }
+
+
+// Calling aligned new with placement syntax.
+// ==========================================
+
+#ifndef UNALIGNED
+// CHECK-LABEL: define {{.*}} @_Z2e0v(
+// CHECK: %[[ALLOC:.*]] = call i8* @_ZnwmSt11align_val_t(i64 512, i64 5)
+// CHECK: call void @_ZdlPvSt11align_val_t(i8* %[[ALLOC]], i64 5)
+void *e0() { return new (std::align_val_t(5)) A; }
+
+// CHECK-LABEL: define {{.*}} @_Z2e1v(
+// CHECK: %[[ALLOC:.*]] = call i8* @_ZN1BnwEmSt11align_val_t(i64 512, i64 5)
+// CHECK: call void @_ZN1BdlEPvSt11align_val_t(i8* %[[ALLOC]], i64 5)
+void *e1() { return new (std::align_val_t(5)) B; }
+#endif
+
+// Variadic placement/non-placement allocation functions.
+// ======================================================
+
+struct OVERALIGNED F {
+ F();
+ void *operator new(size_t, ...);
+ void operator delete(void*, ...);
+ int n[128];
+};
+
+// CHECK-LABEL: define {{.*}} @_Z2f0v(
+// CHECK: %[[ALLOC:.*]] = call i8* (i64, ...) @_ZN1FnwEmz(i64 512, i64 32)
+// Non-placement allocation function, uses normal deallocation lookup which
+// cares about whether a parameter has type std::align_val_t.
+// CHECK: call void (i8*, ...) @_ZN1FdlEPvz(i8* %[[ALLOC]])
+void *f0() { return new F; }
+
+// CHECK-LABEL: define {{.*}} @_Z2f1v(
+// CHECK: %[[ALLOC:.*]] = call i8* (i64, ...) @_ZN1FnwEmz(i64 512, i64 32, i32 %
+// Placement allocation function, uses placement deallocation matching, which
+// passes same arguments and therefore includes alignment.
+// CHECK: call void (i8*, ...) @_ZN1FdlEPvz(i8* %[[ALLOC]], i64 32, i32 %
+void *f1() { return new (q) F; }
+
+struct OVERALIGNED G {
+ G();
+ void *operator new(size_t, std::align_val_t, ...);
+ void operator delete(void*, std::align_val_t, ...);
+ int n[128];
+};
+#ifndef UNALIGNED
+// CHECK-LABEL: define {{.*}} @_Z2g0v
+// CHECK: %[[ALLOC:.*]] = call i8* (i64, i64, ...) @_ZN1GnwEmSt11align_val_tz(i64 512, i64 32)
+// CHECK: call void (i8*, i64, ...) @_ZN1GdlEPvSt11align_val_tz(i8* %[[ALLOC]], i64 32)
+void *g0() { return new G; }
+
+// CHECK-LABEL: define {{.*}} @_Z2g1v
+// CHECK: %[[ALLOC:.*]] = call i8* (i64, i64, ...) @_ZN1GnwEmSt11align_val_tz(i64 512, i64 32, i32 %
+// CHECK: call void (i8*, i64, ...) @_ZN1GdlEPvSt11align_val_tz(i8* %[[ALLOC]], i64 32, i32 %
+void *g1() { return new (q) G; }
+#endif
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx1z-class-deduction.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx1z-class-deduction.cpp
new file mode 100644
index 0000000..0761f21
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cxx1z-class-deduction.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -std=c++1z %s -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %s
+
+template<typename T> struct A {
+ A(T = 0);
+ A(void*);
+};
+
+template<typename T> A(T*) -> A<long>;
+A() -> A<int>;
+
+// CHECK-LABEL: @_Z1fPi(
+void f(int *p) {
+ // CHECK: @_ZN1AIiEC
+ A a{};
+
+ // CHECK: @_ZN1AIlEC
+ A b = p;
+
+ // CHECK: @_ZN1AIxEC
+ A c = 123LL;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx1z-constexpr-if.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx1z-constexpr-if.cpp
new file mode 100644
index 0000000..1469536
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cxx1z-constexpr-if.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - | FileCheck %s --implicit-check-not=should_not_be_used
+
+void should_be_used_1();
+void should_be_used_2();
+void should_be_used_3();
+void should_not_be_used();
+
+struct A {
+ constexpr explicit operator bool() const {
+ return true;
+ }
+};
+
+void f() {
+ if constexpr (false)
+ should_not_be_used();
+ else
+ should_be_used_1();
+
+ if constexpr (true || ({ label: false; }))
+ should_be_used_2();
+ else {
+ goto foo;
+foo: should_not_be_used();
+ }
+ if constexpr (A())
+ should_be_used_3();
+ else
+ should_not_be_used();
+}
+
+// CHECK: should_be_used_1
+// CHECK: should_be_used_2
+// CHECK: should_be_used_3
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx1z-copy-omission.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx1z-copy-omission.cpp
new file mode 100644
index 0000000..b33a218
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cxx1z-copy-omission.cpp
@@ -0,0 +1,107 @@
+// RUN: %clang_cc1 -std=c++1z -emit-llvm -triple x86_64-linux-gnu -o - %s | FileCheck %s
+
+struct A {
+ A(int);
+ A(A&&);
+ A(const A&);
+ ~A();
+
+ operator bool();
+
+ int arr[10];
+};
+
+A f();
+void h();
+
+// CHECK-LABEL: define {{.*}} @_Z1gv(
+void g() {
+ // CHECK: %[[A:.*]] = alloca
+ // CHECK-NOT: alloca
+ // CHECK-NOT: call
+ // CHECK: call {{.*}} @_Z1fv({{.*}}* sret %[[A]])
+ A a = A( A{ f() } );
+ // CHECK-NOT: call
+
+ // CHECK: call void @_Z1hv(
+ h();
+ // CHECK-NOT: call
+
+ // CHECK: call void @_ZN1AD1Ev({{.*}}* %[[A]])
+ // CHECK-NOT: call
+ // CHECK-LABEL: }
+}
+
+void f(A);
+
+// CHECK-LABEL: define {{.*}} @_Z1hv(
+void h() {
+ // CHECK: %[[A:.*]] = alloca
+ // CHECK-NOT: alloca
+ // CHECK-NOT: call
+
+ // CHECK: call {{.*}} @_Z1fv({{.*}}* sret %[[A]])
+ // CHECK-NOT: call
+ // CHECK: call {{.*}} @_Z1f1A({{.*}}* %[[A]])
+ f(f());
+ // CHECK-NOT: call
+ // CHECK: call void @_ZN1AD1Ev({{.*}}* %[[A]])
+
+ // CHECK: call void @_Z1hv(
+ h();
+
+ // CHECK-NOT: call
+ // CHECK-LABEL: }
+}
+
+// We still pass classes with trivial copy/move constructors and destructors in
+// registers, even if the copy is formally omitted.
+struct B {
+ B(int);
+ int n;
+};
+
+B fB();
+void fB(B);
+
+// CHECK-LABEL: define {{.*}} @_Z1iv(
+void i() {
+ // CHECK: %[[B:.*]] = alloca
+ // CHECK-NOT: alloca
+ // CHECK-NOT: call
+
+ // CHECK: %[[B_N:.*]] = call i32 @_Z2fBv()
+ // CHECK-NOT: call
+ // CHECK: store i32 %[[B_N]],
+ // CHECK-NOT: call
+ // CHECK: %[[B_N:.*]] = load i32
+ // CHECK-NOT: call
+ // CHECK: call void @_Z2fB1B(i32 %[[B_N]])
+ fB(fB());
+
+ // CHECK-LABEL: }
+}
+
+// CHECK-LABEL: define {{.*}} @_Z1jv(
+void j() {
+ // CHECK: alloca %{{.*}}*
+ // CHECK: %[[OUTERTEMP:.*]] = alloca %{{.*}}
+ // CHECK: %[[INNERTEMP:.*]] = alloca %{{.*}}
+ // CHECK: call void @_ZN1AC1Ei(%{{.*}} %[[INNERTEMP]], i32 1)
+ // CHECK: call zeroext i1 @_ZN1AcvbEv(%{{.*}} %[[INNERTEMP]])
+ // CHECK: br i1
+ //
+ // CHECK: call void @_ZN1AC1EOS_(%{{.*}} %[[OUTERTEMP]], %{{.*}} %[[INNERTEMP]])
+ // CHECK: br label
+ //
+ // CHECK: call void @_ZN1AC1Ei(%{{.*}} %[[OUTERTEMP]], i32 2)
+ // CHECK: br label
+ //
+ // CHECK: call void @_ZN1AD1Ev(%{{.*}} %[[INNERTEMP]])
+ A &&a = A(1) ?: A(2);
+
+ // CHECK: call void @_Z1iv()
+ i();
+
+ // CHECK: call void @_ZN1AD1Ev(%{{.*}} %[[OUTERTEMP]])
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx1z-decomposition.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx1z-decomposition.cpp
new file mode 100644
index 0000000..b921200
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cxx1z-decomposition.cpp
@@ -0,0 +1,118 @@
+// RUN: %clang_cc1 -std=c++1z -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s
+
+namespace std {
+ using size_t = decltype(sizeof(0));
+ template<typename> struct tuple_size;
+ template<size_t, typename> struct tuple_element;
+}
+
+struct Y { int n; };
+struct X { X(); X(Y); X(const X&); ~X(); };
+
+struct A { int a : 13; bool b; };
+
+struct B {};
+template<> struct std::tuple_size<B> { enum { value = 2 }; };
+template<> struct std::tuple_element<0,B> { using type = X; };
+template<> struct std::tuple_element<1,B> { using type = const int&; };
+template<int N> auto get(B) {
+ if constexpr (N == 0)
+ return Y();
+ else
+ return 0.0;
+}
+
+using C = int[2];
+
+typedef int D __attribute__((ext_vector_type(2)));
+
+using E = _Complex int;
+
+template<typename T> T &make();
+
+// CHECK: @_ZDC2a12a2E = global {{.*}} zeroinitializer, align 4
+auto [a1, a2] = make<A>();
+// CHECK: @_ZDC2b12b2E = global {{.*}} zeroinitializer, align 1
+// CHECK: @b1 = global {{.*}}* null, align 8
+// CHECK: @_ZGR2b1_ = internal global {{.*}} zeroinitializer, align 1
+// CHECK: @b2 = global i32* null, align 8
+// CHECK: @_ZGR2b2_ = internal global i32 0, align 4
+auto [b1, b2] = make<B>();
+// CHECK: @_ZDC2c12c2E = global [2 x i32]* null, align 8
+auto &[c1, c2] = make<C>();
+// CHECK: @_ZDC2d12d2E = global <2 x i32> zeroinitializer, align 8
+auto [d1, d2] = make<D>();
+// CHECK: @_ZDC2e12e2E = global { i32, i32 } zeroinitializer, align 4
+auto [e1, e2] = make<E>();
+
+// CHECK: call {{.*}}* @_Z4makeI1AERT_v()
+// CHECK: call {{.*}}memcpy{{.*}}@_ZDC2a12a2E
+
+// CHECK: @_Z4makeI1BERT_v()
+// CHECK: call i32 @_Z3getILi0EEDa1B()
+// CHECK: call void @_ZN1XC1E1Y({{.*}}* @_ZGR2b1_, i32
+// CHECK: call i32 @__cxa_atexit({{.*}}@_ZN1XD1Ev{{.*}}@_ZGR2b1_
+// CHECK: store {{.*}}* @_ZGR2b1_,
+//
+// CHECK: call double @_Z3getILi1EEDa1B()
+// CHECK: fptosi double %{{.*}} to i32
+// CHECK: store i32 %{{.*}}, i32* @_ZGR2b2_
+// CHECK: store i32* @_ZGR2b2_, i32** @b2
+
+// CHECK: call {{.*}}* @_Z4makeIA2_iERT_v()
+// CHECK: store {{.*}}, [2 x i32]** @_ZDC2c12c2E
+
+// CHECK: call {{.*}}* @_Z4makeIDv2_iERT_v()
+// CHECK: store {{.*}}, <2 x i32>* @_ZDC2d12d2E, align 8
+
+// CHECK: call {{.*}}* @_Z4makeICiERT_v()
+// CHECK: store i32 %{{.*}}, i32* getelementptr inbounds ({ i32, i32 }, { i32, i32 }* @_ZDC2e12e2E, i32 0, i32 0)
+// CHECK: store i32 %{{.*}}, i32* getelementptr inbounds ({ i32, i32 }, { i32, i32 }* @_ZDC2e12e2E, i32 0, i32 1)
+
+// CHECK: define i32 @_Z12test_globalsv()
+int test_globals() {
+ return a2 + b2 + c2 + d2 + e2;
+ // CHECK: load i8, i8* getelementptr inbounds (%struct.A, %struct.A* @_ZDC2a12a2E, i32 0, i32 1)
+ //
+ // CHECK: %[[b2:.*]] = load i32*, i32** @b2
+ // CHECK: load i32, i32* %[[b2]]
+ //
+ // CHECK: %[[c1c2:.*]] = load [2 x i32]*, [2 x i32]** @_ZDC2c12c2E
+ // CHECK: %[[c2:.*]] = getelementptr inbounds [2 x i32], [2 x i32]* %[[c1c2]], i64 0, i64 1
+ // CHECK: load i32, i32* %[[c2]]
+ //
+ // CHECK: %[[d1d2:.*]] = load <2 x i32>, <2 x i32>* @_ZDC2d12d2E
+ // CHECK: extractelement <2 x i32> %[[d1d2]], i32 1
+ //
+ // CHECK: load i32, i32* getelementptr inbounds ({ i32, i32 }, { i32, i32 }* @_ZDC2e12e2E, i32 0, i32 1)
+}
+
+// CHECK: define i32 @_Z11test_localsv()
+int test_locals() {
+ auto [b1, b2] = make<B>();
+
+ // CHECK: @_Z4makeI1BERT_v()
+ // CHECK: call i32 @_Z3getILi0EEDa1B()
+ // CHECK: call void @_ZN1XC1E1Y({{.*}}* %[[b1:.*]], i32
+ //
+ // CHECK: call double @_Z3getILi1EEDa1B()
+ // CHECK: %[[cvt:.*]] = fptosi double %{{.*}} to i32
+ // CHECK: store i32 %[[cvt]], i32* %[[b2:.*]],
+ // CHECK: store i32* %[[b2]], i32** %[[b2ref:.*]],
+
+ return b2;
+ // CHECK: %[[b2:.*]] = load i32*, i32** %[[b2ref]]
+ // CHECK: load i32, i32* %[[b2]]
+
+ // CHECK: call {{.*}}@_ZN1XD1Ev({{.*}}%[[b1]])
+}
+
+// CHECK: define void @_Z13test_bitfieldR1A(
+void test_bitfield(A &a) {
+ auto &[a1, a2] = a;
+ a1 = 5;
+ // CHECK: load i16, i16* %[[BITFIELD:.*]],
+ // CHECK: and i16 %{{.*}}, -8192
+ // CHECK: or i16 %{{.*}}, 5
+ // CHECK: store i16 %{{.*}}, i16* %[[BITFIELD]],
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx1z-eval-order.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx1z-eval-order.cpp
new file mode 100644
index 0000000..04c1b50
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cxx1z-eval-order.cpp
@@ -0,0 +1,271 @@
+// RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - -triple %itanium_abi_triple | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ITANIUM
+// RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - -triple i686-windows | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-WINDOWS
+// RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - -triple x86_64-windows | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-WINDOWS
+
+struct B;
+struct A {
+ A();
+ A(const A&);
+
+ void operator[](B b);
+
+ int a_member_f(B);
+};
+struct B {
+ B();
+ ~B();
+};
+
+struct C {
+ operator int *();
+ A *operator->();
+ void operator->*(A);
+ friend void operator->*(C, B);
+
+ friend void operator<<(C, B);
+ friend void operator>>(C, B);
+ void operator<<(A);
+ void operator>>(A);
+
+ void operator=(A);
+ void operator+=(A);
+ friend void operator+=(C, B);
+
+ void operator,(A);
+ friend void operator,(C, B);
+
+ void operator&&(A);
+ void operator||(A);
+ friend void operator&&(C, B);
+ friend void operator||(C, B);
+};
+
+A make_a();
+A *make_a_ptr();
+int A::*make_mem_ptr_a();
+void (A::*make_mem_fn_ptr_a())();
+B make_b();
+C make_c();
+void side_effect();
+
+void callee(A);
+void (*get_f())(A);
+
+
+// CHECK-LABEL: define {{.*}}@{{.*}}postfix_before_args{{.*}}(
+void postfix_before_args() {
+ // CHECK: call {{.*}}@{{.*}}get_f{{.*}}(
+ // CHECK-ITANIUM: call {{.*}}@_ZN1AC1Ev(
+ // CHECK-WINDOWS: call {{.*}}@"??0A@@Q{{AE|EAA}}@XZ"(
+ // CHECK: call {{.*}}%{{.*}}(
+ get_f()(A{});
+
+ // CHECK: call {{.*}}@{{.*}}side_effect{{.*}}(
+ // CHECK-ITANIUM: call {{.*}}@_ZN1AC1Ev(
+ // CHECK-WINDOWS: call {{.*}}@"??0A@@Q{{AE|EAA}}@XZ"(
+ // CHECK: call {{.*}}@{{.*}}callee{{.*}}(
+ (side_effect(), callee)(A{});
+// CHECK: }
+}
+
+
+// CHECK-LABEL: define {{.*}}@{{.*}}dot_lhs_before_rhs{{.*}}(
+void dot_lhs_before_rhs() {
+ // CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}a_member_f{{.*}}(
+ make_a().a_member_f(make_b());
+
+ // CHECK: call {{.*}}@{{.*}}make_a_ptr{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}a_member_f{{.*}}(
+ make_a_ptr()->a_member_f(make_b());
+
+ // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}a_member_f{{.*}}(
+ make_c()->a_member_f(make_b());
+// CHECK: }
+}
+
+
+// CHECK-LABEL: define {{.*}}@{{.*}}array_lhs_before_rhs{{.*}}(
+void array_lhs_before_rhs() {
+ int (&get_arr())[10];
+ extern int get_index();
+
+ // CHECK: call {{.*}}@{{.*}}get_arr{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}get_index{{.*}}(
+ get_arr()[get_index()] = 0;
+
+ // CHECK: call {{.*}}@{{.*}}get_index{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}get_arr{{.*}}(
+ get_index()[get_arr()] = 0;
+
+ // CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
+ // CHECK: call
+ make_a()[make_b()];
+
+ // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}get_index{{.*}}(
+ // CHECK: call
+ make_c()[get_index()] = 0;
+
+ // CHECK: call {{.*}}@{{.*}}get_index{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
+ // CHECK: call
+ get_index()[make_c()] = 0;
+// CHECK: }
+}
+
+
+void *operator new(decltype(sizeof(0)), C);
+
+// CHECK-LABEL: define {{.*}}@{{.*}}alloc_before_init{{.*}}(
+void alloc_before_init() {
+ struct Q { Q(A) {} };
+ // CHECK-ITANIUM: call {{.*}}@_Znw{{.*}}(
+ // CHECK-WINDOWS: call {{.*}}@"??2@YAP{{EAX_K|AXI}}@Z"(
+ // CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
+ delete new Q(make_a());
+
+ // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
+ new (make_c()) Q(make_a());
+// CHECK: }
+}
+
+
+// CHECK-LABEL: define {{.*}}@{{.*}}dotstar_lhs_before_rhs{{.*}}(
+int dotstar_lhs_before_rhs() {
+ // CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_mem_ptr_a{{.*}}(
+ int a = make_a().*make_mem_ptr_a();
+
+ // CHECK: call {{.*}}@{{.*}}make_a_ptr{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_mem_ptr_a{{.*}}(
+ int b = make_a_ptr()->*make_mem_ptr_a();
+
+ // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
+ make_c()->*make_a();
+
+ // FIXME: For MS ABI, the order of destruction of parameters here will not be
+ // reverse construction order (parameters are destroyed left-to-right in the
+ // callee). That sadly seems unavoidable; the rules are not implementable as
+ // specified. If we changed parameter destruction order for these functions
+ // to right-to-left, we could make the destruction order match for all cases
+ // other than indirect calls, but we can't completely avoid the problem.
+ //
+ // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
+ make_c()->*make_b();
+
+ // CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_mem_fn_ptr_a{{.*}}(
+ // CHECK: call
+ (make_a().*make_mem_fn_ptr_a())();
+
+ // CHECK: call {{.*}}@{{.*}}make_a_ptr{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_mem_fn_ptr_a{{.*}}(
+ // CHECK: call
+ (make_a_ptr()->*make_mem_fn_ptr_a())();
+
+ return a + b;
+// CHECK: }
+}
+
+
+// CHECK-LABEL: define {{.*}}@{{.*}}assign_rhs_before_lhs{{.*}}(
+void assign_rhs_before_lhs() {
+ extern int &lhs_ref(), rhs();
+
+ // CHECK: call {{.*}}@{{.*}}rhs{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}lhs_ref{{.*}}(
+ lhs_ref() = rhs();
+
+ // CHECK: call {{.*}}@{{.*}}rhs{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}lhs_ref{{.*}}(
+ lhs_ref() += rhs();
+
+ // CHECK: call {{.*}}@{{.*}}rhs{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}lhs_ref{{.*}}(
+ lhs_ref() %= rhs();
+
+ // CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
+ make_c() = make_a();
+
+ // CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
+ make_c() += make_a();
+
+ // CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
+ make_c() += make_b();
+// CHECK: }
+}
+
+// CHECK-LABEL: define {{.*}}@{{.*}}shift_lhs_before_rhs{{.*}}(
+void shift_lhs_before_rhs() {
+ extern int lhs(), rhs();
+
+ // CHECK: call {{.*}}@{{.*}}lhs{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}rhs{{.*}}(
+ (void)(lhs() << rhs());
+
+ // CHECK: call {{.*}}@{{.*}}lhs{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}rhs{{.*}}(
+ (void)(lhs() >> rhs());
+
+ // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
+ make_c() << make_a();
+
+ // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
+ make_c() >> make_a();
+
+ // FIXME: This is not correct for Windows ABIs, see above.
+ // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
+ make_c() << make_b();
+
+ // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
+ make_c() >> make_b();
+// CHECK: }
+}
+
+// CHECK-LABEL: define {{.*}}@{{.*}}comma_lhs_before_rhs{{.*}}(
+void comma_lhs_before_rhs() {
+ // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
+ make_c() , make_a();
+
+ // FIXME: This is not correct for Windows ABIs, see above.
+ // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
+ make_c() , make_b();
+}
+
+// CHECK-LABEL: define {{.*}}@{{.*}}andor_lhs_before_rhs{{.*}}(
+void andor_lhs_before_rhs() {
+ // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
+ make_c() && make_a();
+
+ // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
+ make_c() || make_a();
+
+ // FIXME: This is not correct for Windows ABIs, see above.
+ // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
+ make_c() && make_b();
+
+ // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
+ // CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
+ make_c() || make_b();
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx1z-fold-expression.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx1z-fold-expression.cpp
new file mode 100644
index 0000000..5dac66b
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cxx1z-fold-expression.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -std=c++1z -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
+
+template<int> struct A {};
+template<int ...N> void foldr(A<(N + ...)>);
+template<int ...N> void foldl(A<(... + N)>);
+template<int ...N> void foldr1(A<(N + ... + 1)>);
+template<int ...N> void foldl1(A<(1 + ... + N)>);
+void use() {
+ foldr<1, 2, 3>({});
+ foldl<1, 2, 3>({});
+ foldr1<1, 2, 3>({});
+ foldl1<1, 2, 3>({});
+ // CHECK-DAG: @_Z5foldrIJLi1ELi2ELi3EEEv1AIXfrplT_EE(
+ // CHECK-DAG: @_Z5foldlIJLi1ELi2ELi3EEEv1AIXflplT_EE(
+ // CHECK-DAG: @_Z6foldr1IJLi1ELi2ELi3EEEv1AIXfRplT_Li1EEE(
+ // CHECK-DAG: @_Z6foldl1IJLi1ELi2ELi3EEEv1AIXfLplLi1ET_EE(
+}
+
+template<int ...N> using Foldr = A<(N + ...)>;
+template<int ...N> using Foldl = A<(... + N)>;
+template<int ...N> using Foldr1 = A<(N + ... + 1)>;
+template<int ...N> using Foldl1 = A<(1 + ... + N)>;
+
+template<int ...A> struct Partial {
+ template<int ...B> void foldr(Foldr<A..., B..., A..., B...>);
+ template<int ...B> void foldl(Foldl<A..., B..., A..., B...>);
+ template<int ...B> void foldr1(Foldr1<A..., B..., A..., B...>);
+ template<int ...B> void foldl1(Foldl1<A..., B..., A..., B...>);
+};
+void use(Partial<1, 2> p) {
+ p.foldr<3, 4>({});
+ p.foldl<3, 4>({});
+ p.foldr1<3, 4>({});
+ p.foldl1<3, 4>({});
+ // CHECK-DAG: @_ZN7PartialIJLi1ELi2EEE5foldrIJLi3ELi4EEEEv1AIXplLi1EplLi2EfRplT_plLi1EplLi2EfrplT_EE(
+ // CHECK-DAG: @_ZN7PartialIJLi1ELi2EEE5foldlIJLi3ELi4EEEEv1AIXfLplplplfLplplLi1ELi2ET_Li1ELi2ET_EE
+ // CHECK-DAG: @_ZN7PartialIJLi1ELi2EEE6foldr1IJLi3ELi4EEEEv1AIXplLi1EplLi2EfRplT_plLi1EplLi2EfRplT_Li1EEE(
+ // CHECK-DAG: @_ZN7PartialIJLi1ELi2EEE6foldl1IJLi3ELi4EEEEv1AIXfLplplplfLplplplLi1ELi1ELi2ET_Li1ELi2ET_EE(
+}
+
+extern int n;
+template<int ...N> void f() {
+ (n = ... = N);
+}
+template void f<>();
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx1z-init-statement.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx1z-init-statement.cpp
new file mode 100644
index 0000000..5c05212
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cxx1z-init-statement.cpp
@@ -0,0 +1,70 @@
+// RUN: %clang_cc1 -std=c++1z -triple x86_64-apple-macosx10.7.0 -emit-llvm -o - %s -w | FileCheck %s
+
+typedef int T;
+void f() {
+ // CHECK: %[[A:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i32 5, i32* %[[A]], align 4
+ // CHECK-NEXT: %[[B:.*]] = load i32, i32* %[[A]], align 4
+ // CHECK-NEXT %[[C:.*]] = icmp slt i32 %[[B]], 8
+ if (int a = 5; a < 8)
+ ;
+}
+
+void f1() {
+ // CHECK: %[[A:.*]] = alloca i32, align 4
+ // CHECK-NEXT: %[[B:.*]] = alloca i32, align 4
+ // CHECK-NEXT: %[[C:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i32 5, i32* %[[B]], align 4
+ // CHECK-NEXT: store i32 7, i32* %[[C]], align 4
+ if (int a, b = 5; int c = 7)
+ ;
+}
+
+int f2() {
+ // CHECK: %[[A:.*]] = alloca i32, align 4
+ // CHECK-NEXT: %[[B:.*]] = call i32 @_Z2f2v()
+ // CHECK-NEXT: store i32 7, i32* %[[A]], align 4
+ // CHECK-NEXT: %[[C:.*]] = load i32, i32* %[[A]], align 4
+ // CHECK-NEXT: %[[D:.*]] = icmp ne i32 %[[C]], 0
+ if (T{f2()}; int c = 7)
+ ;
+ return 2;
+}
+
+void g() {
+ // CHECK: %[[A:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i32 5, i32* %[[A]], align 4
+ // CHECK-NEXT: %[[B:.*]] = load i32, i32* %[[A]], align 4
+ // CHECK-NEXT: switch i32 %[[B]], label %[[C:.*]] [
+ switch (int a = 5; a) {
+ case 0:
+ break;
+ }
+}
+
+void g1() {
+ // CHECK: %[[A:.*]] = alloca i32, align 4
+ // CHECK-NEXT: %[[B:.*]] = alloca i32, align 4
+ // CHECK-NEXT: %[[C:.*]] = alloca i32, align 4
+ // CHECK-NEXT: store i32 5, i32* %[[B]], align 4
+ // CHECK-NEXT: store i32 7, i32* %[[C]], align 4
+ // CHECK-NEXT: %[[D:.*]] = load i32, i32* %[[C]], align 4
+ // CHECK-NEXT: switch i32 %[[D]], label %[[E:.*]] [
+ switch (int a, b = 5; int c = 7) {
+ case 0:
+ break;
+ }
+}
+
+int g2() {
+ // CHECK: %[[A:.*]] = alloca i32, align 4
+ // CHECK-NEXT: %[[B:.*]] = call i32 @_Z2f2v()
+ // CHECK-NEXT: store i32 7, i32* %[[A]], align 4
+ // CHECK-NEXT: %[[C:.*]] = load i32, i32* %[[A]], align 4
+ // CHECK-NEXT: switch i32 %[[C]], label %[[E:.*]] [
+ switch (T{f2()}; int c = 7) {
+ case 0:
+ break;
+ }
+ return 2;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx1z-initializer-aggregate.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx1z-initializer-aggregate.cpp
new file mode 100644
index 0000000..f59ec51
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cxx1z-initializer-aggregate.cpp
@@ -0,0 +1,132 @@
+// RUN: %clang_cc1 -std=c++1z %s -triple x86_64-linux-gnu -fexceptions -fcxx-exceptions -emit-llvm -o - | FileCheck %s
+
+namespace Constant {
+ struct A {
+ int n;
+ char k;
+ ~A();
+ };
+
+ struct B {
+ char k2;
+ };
+
+ struct C : B {};
+
+ struct D : A, C {};
+
+ C c1 = {};
+ C c2 = {1};
+ // CHECK: @_ZN8Constant2c1E = global { i8 } zeroinitializer, align 1
+ // CHECK: @_ZN8Constant2c2E = global { i8 } { i8 1 }, align 1
+
+ // Test packing bases into tail padding.
+ D d1 = {};
+ D d2 = {1, 2, 3};
+ D d3 = {1};
+ // CHECK: @_ZN8Constant2d1E = global { i32, i8, i8 } zeroinitializer, align 4
+ // CHECK: @_ZN8Constant2d2E = global { i32, i8, i8 } { i32 1, i8 2, i8 3 }, align 4
+ // CHECK: @_ZN8Constant2d3E = global { i32, i8, i8 } { i32 1, i8 0, i8 0 }, align 4
+
+ // CHECK-LABEL: define {{.*}}global_var_init
+ // CHECK: call {{.*}} @__cxa_atexit({{.*}} @_ZN8Constant1DD1Ev {{.*}} @_ZN8Constant2d1E
+
+ // CHECK-LABEL: define {{.*}}global_var_init
+ // CHECK: call {{.*}} @__cxa_atexit({{.*}} @_ZN8Constant1DD1Ev {{.*}} @_ZN8Constant2d2E
+
+ // CHECK-LABEL: define {{.*}}global_var_init
+ // CHECK: call {{.*}} @__cxa_atexit({{.*}} @_ZN8Constant1DD1Ev {{.*}} @_ZN8Constant2d3E
+}
+
+namespace Dynamic {
+ struct A {
+ A();
+ A(int);
+ A(const char*, unsigned);
+ ~A();
+ void *p;
+ };
+
+ struct B {
+ ~B();
+ int n = 5;
+ };
+
+ struct C {
+ C(bool = true);
+ };
+
+ int f(), g(), h(), i();
+ struct D : A, B, C {
+ int n = f();
+ };
+
+ D d1 = {};
+ // CHECK-LABEL: define {{.*}}global_var_init
+ // CHECK: call void @_ZN7Dynamic1AC2Ev({{.*}} @_ZN7Dynamic2d1E
+ // CHECK: store i32 5, {{.*}}i8* getelementptr inbounds {{.*}} @_ZN7Dynamic2d1E{{.*}}, i64 8
+ // CHECK: invoke void @_ZN7Dynamic1CC2Eb({{.*}} @_ZN7Dynamic2d1E{{.*}}, i1 zeroext true)
+ // CHECK: unwind label %[[UNWIND:.*]]
+ // CHECK: invoke i32 @_ZN7Dynamic1fEv()
+ // CHECK: unwind label %[[UNWIND:.*]]
+ // CHECK: store i32 {{.*}}, i32* getelementptr {{.*}} @_ZN7Dynamic2d1E, i32 0, i32 2
+ // CHECK: call {{.*}} @__cxa_atexit({{.*}} @_ZN7Dynamic1DD1Ev {{.*}} @_ZN7Dynamic2d1E
+ // CHECK: ret
+ //
+ // UNWIND:
+ // CHECK: call void @_ZN7Dynamic1BD1Ev({{.*}}i8* getelementptr inbounds {{.*}} @_ZN7Dynamic2d1E{{.*}}, i64 8
+ // CHECK: call void @_ZN7Dynamic1AD1Ev({{.*}} @_ZN7Dynamic2d1E
+
+ D d2 = {1, 2, false};
+ // CHECK-LABEL: define {{.*}}global_var_init
+ // CHECK: call void @_ZN7Dynamic1AC1Ei({{.*}} @_ZN7Dynamic2d2E{{.*}}, i32 1)
+ // CHECK: store i32 2, {{.*}}i8* getelementptr inbounds {{.*}}@_ZN7Dynamic2d2E{{.*}}, i64 8
+ // CHECK: invoke void @_ZN7Dynamic1CC1Eb({{.*}} @_ZN7Dynamic2d2E{{.*}}, i1 zeroext false)
+ // CHECK: invoke i32 @_ZN7Dynamic1fEv()
+ // CHECK: store i32 {{.*}}, i32* getelementptr {{.*}} @_ZN7Dynamic2d2E, i32 0, i32 2
+ // CHECK: call {{.*}} @__cxa_atexit({{.*}} @_ZN7Dynamic1DD1Ev {{.*}} @_ZN7Dynamic2d2E
+ // CHECK: ret void
+
+ D d3 = {g(), h(), {}, i()};
+ // CHECK-LABEL: define {{.*}}global_var_init
+ // CHECK: %[[G_CALL:.*]] = call i32 @_ZN7Dynamic1gEv()
+ // CHECK: call void @_ZN7Dynamic1AC1Ei({{.*}} @_ZN7Dynamic2d3E{{.*}}, i32 %[[G_CALL]])
+ // CHECK: %[[H_CALL:.*]] = invoke i32 @_ZN7Dynamic1hEv()
+ // CHECK: unwind label %[[DESTROY_A_LPAD:.*]]
+ // CHECK: store i32 %[[H_CALL]], {{.*}}i8* getelementptr inbounds {{.*}} @_ZN7Dynamic2d3E{{.*}}, i64 8
+ // CHECK: invoke void @_ZN7Dynamic1CC2Eb({{.*}} @_ZN7Dynamic2d3E{{.*}}, i1 zeroext true)
+ // CHECK: unwind label %[[DESTROY_AB_LPAD:.*]]
+ // CHECK: %[[I_CALL:.*]] = invoke i32 @_ZN7Dynamic1iEv()
+ // CHECK: unwind label %[[DESTROY_AB_LPAD:.*]]
+ // CHECK: store i32 %[[I_CALL]], i32* getelementptr {{.*}} @_ZN7Dynamic2d3E, i32 0, i32 2
+ // CHECK: call {{.*}} @__cxa_atexit({{.*}} @_ZN7Dynamic1DD1Ev {{.*}} @_ZN7Dynamic2d3E to i8*
+ // CHECK: ret
+ //
+ // DESTROY_A_LPAD:
+ // CHECK: br label %[[A_CLEANUP:.*]]
+ //
+ // DESTROY_B_LPAD:
+ // CHECK: call void @_ZN7Dynamic1BD1Ev({{.*}}i8* getelementptr inbounds {{.*}} @_ZN7Dynamic2d3E{{.*}}, i64 8
+ // CHECK: br label %[[A_CLEANUP:.*]]
+ //
+ // A_CLEANUP:
+ // CHECK: call void @_ZN7Dynamic1AD1Ev({{.*}} @_ZN7Dynamic2d3E
+}
+
+namespace Instantiated1 {
+ struct A { A(); };
+ struct B : A { using A::A; };
+ template<int> B v({});
+ template B v<0>;
+ // CHECK-LABEL: define {{.*}}global_var_init{{.*}} comdat($_ZN13Instantiated11vILi0EEE) {
+ // CHECK: call void @_ZN13Instantiated11BC1Ev(%{{.*}}* @_ZN13Instantiated11vILi0EEE)
+}
+
+namespace Instantiated2 {
+ struct A { A(); };
+ struct B : A {};
+ template<int> B v({});
+ template B v<0>;
+ // CHECK-LABEL: define {{.*}}global_var_init{{.*}} comdat($_ZN13Instantiated21vILi0EEE) {
+ // CHECK: call void @_ZN13Instantiated21AC2Ev(
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx1z-inline-variables.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx1z-inline-variables.cpp
new file mode 100644
index 0000000..938ebbb
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cxx1z-inline-variables.cpp
@@ -0,0 +1,139 @@
+// RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - -triple x86_64-linux-gnu | FileCheck %s
+
+struct Q {
+ // CHECK: @_ZN1Q1kE = linkonce_odr constant i32 5, comdat
+ static constexpr int k = 5;
+};
+const int &r = Q::k;
+
+int f();
+
+// const does not imply internal linkage.
+// CHECK: @external_inline = linkonce_odr constant i32 5, comdat
+inline const int external_inline = 5;
+const int &use1 = external_inline;
+
+// static still does, though.
+// CHECK: @_ZL15internal_inline = internal constant i32 5
+static inline const int internal_inline = 5;
+const int &use2 = internal_inline;
+
+int a = f();
+// CHECK: @b = linkonce_odr global i32 0, comdat
+// CHECK: @_ZGV1b = linkonce_odr global i64 0, comdat($b)
+inline int b = f();
+int c = f();
+
+// For compatibility with C++11 and C++14, an out-of-line declaration of a
+// static constexpr local variable promotes the variable to weak_odr.
+struct compat {
+ static constexpr int a = 1;
+ static constexpr int b = 2;
+ static constexpr int c = 3;
+ static inline constexpr int d = 4;
+ static const int e = 5;
+ static const int f = 6;
+ static const int g = 7;
+};
+const int &compat_use_before_redecl = compat::b;
+const int compat::a;
+const int compat::b;
+const int compat::c;
+const int compat::d;
+const int compat::e;
+constexpr int compat::f;
+constexpr inline int compat::g;
+const int &compat_use_after_redecl1 = compat::c;
+const int &compat_use_after_redecl2 = compat::d;
+const int &compat_use_after_redecl3 = compat::g;
+// CHECK-DAG: @_ZN6compat1bE = weak_odr constant i32 2
+// CHECK-DAG: @_ZN6compat1aE = weak_odr constant i32 1
+// CHECK-DAG: @_ZN6compat1cE = weak_odr constant i32 3
+// CHECK-DAG: @_ZN6compat1dE = linkonce_odr constant i32 4
+// CHECK-DAG: @_ZN6compat1eE = constant i32 5
+// CHECK-DAG: @_ZN6compat1fE = weak_odr constant i32 6
+// CHECK-DAG: @_ZN6compat1gE = linkonce_odr constant i32 7
+
+template<typename T> struct X {
+ static int a;
+ static inline int b;
+ static int c;
+ static const int d;
+ static int e;
+};
+// CHECK: @_ZN1XIiE1aE = linkonce_odr global i32 10
+// CHECK: @_ZN1XIiE1bE = global i32 20
+// CHECK-NOT: @_ZN1XIiE1cE
+// CHECK: @_ZN1XIiE1dE = linkonce_odr constant i32 40
+// CHECK: @_ZN1XIiE1eE = linkonce_odr global i32 50
+template<> inline int X<int>::a = 10;
+int &use3 = X<int>::a;
+template<> int X<int>::b = 20;
+template<> inline int X<int>::c = 30;
+template<typename T> constexpr int X<T>::d = 40;
+template<typename T> inline int X<T>::e = 50;
+const int *use_x_int_d = &X<int>::d;
+const int *use_x_int_e = &X<int>::e;
+
+template<typename T> struct Y;
+template<> struct Y<int> {
+ static constexpr int a = 123;
+ static constexpr int b = 456;
+ static constexpr int c = 789;
+};
+// CHECK: @_ZN1YIiE1aE = weak_odr constant i32 123
+constexpr int Y<int>::a;
+// CHECK: @_ZN1YIiE1bE = linkonce_odr constant i32 456
+const int &yib = Y<int>::b;
+// CHECK-NOT: @_ZN1YIiE1cE
+
+// CHECK-LABEL: define {{.*}}global_var_init
+// CHECK: call i32 @_Z1fv
+
+// CHECK-LABEL: define {{.*}}global_var_init
+// CHECK-NOT: comdat
+// CHECK-SAME: {{$}}
+// CHECK: load atomic {{.*}} acquire
+// CHECK: br
+// CHECK: __cxa_guard_acquire(i64* @_ZGV1b)
+// CHECK: br
+// CHECK: call i32 @_Z1fv
+// CHECK: __cxa_guard_release(i64* @_ZGV1b)
+
+// CHECK-LABEL: define {{.*}}global_var_init
+// CHECK: call i32 @_Z1fv
+
+template<typename T> inline int d = f();
+int e = d<int>;
+
+// CHECK-LABEL: define {{.*}}global_var_init{{.*}}comdat
+// CHECK: _ZGV1dIiE
+// CHECK-NOT: __cxa_guard_acquire(i64* @_ZGV1b)
+// CHECK: call i32 @_Z1fv
+// CHECK-NOT: __cxa_guard_release(i64* @_ZGV1b)
+
+namespace PR35599 {
+struct Marker1 {};
+struct Marker2 {};
+
+template <typename>
+struct Foo {
+ struct Bar { Bar(); };
+ inline static Bar bar;
+};
+
+void run() {
+ // All we want here are ODR uses. Anything that requires that the type is
+ // complete is uninteresting.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunused-value"
+ Foo<Marker1>::bar;
+#pragma clang diagnostic pop
+ static_cast<void>(Foo<Marker2>::bar);
+}
+
+// CHECK-LABEL: define {{.*}}global_var_init{{.*}}comdat
+// CHECK: call void @_ZN7PR355993FooINS_7Marker1EE3BarC1Ev
+// CHECK-LABEL: define {{.*}}global_var_init{{.*}}comdat
+// CHECK: call void @_ZN7PR355993FooINS_7Marker2EE3BarC1Ev
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx1z-lambda-star-this.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx1z-lambda-star-this.cpp
new file mode 100644
index 0000000..114791c
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cxx1z-lambda-star-this.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -std=c++1y -triple i686-pc-windows-msvc -emit-llvm %s -o - | FileCheck %s
+//CHECK: %[[A_LAMBDA:.*]] = type { %struct.A }
+//CHECK: %[[B_LAMBDA:.*]] = type { %struct.B* }
+struct A {
+ double a = 111;
+ auto foo() { return [*this] { return a; }; }
+};
+
+namespace ns1 {
+int X = A{}.foo()();
+} //end ns1
+
+//CHECK: @"?foo@A@@QAE?A?<auto>@@XZ"(%struct.A* %this, %class.anon* noalias sret %[[A_LAMBDA_RETVAL:.*]])
+// get the first object with the closure type, which is of type 'struct.A'
+//CHECK: %[[I0:.+]] = getelementptr inbounds %[[A_LAMBDA]], %[[A_LAMBDA]]* %[[A_LAMBDA_RETVAL]], i32 0, i32 0
+//CHECK: %[[I1:.+]] = bitcast %struct.A* %[[I0]] to i8*
+//CHECK: %[[I2:.+]] = bitcast %struct.A* %this1 to i8*
+// copy the contents ...
+//CHECK: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 8 %[[I1]], i8* align 8 %[[I2]], i32 8, i1 false)
+
+struct B {
+ double b = 222;
+ auto bar() { return [this] { return b; }; };
+};
+
+namespace ns2 {
+int X = B{}.bar()();
+}
+//CHECK: @"?bar@B@@QAE?A?<auto>@@XZ"(%struct.B* %this, %class.anon.0* noalias sret %agg.result)
+//CHECK: %[[I20:.+]] = getelementptr inbounds %class.anon.0, %class.anon.0* %agg.result, i32 0, i32 0
+//CHECK: store %struct.B* %this1, %struct.B** %[[I20]], align 4
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx1z-noexcept-function-type.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx1z-noexcept-function-type.cpp
new file mode 100644
index 0000000..d2d06fb
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cxx1z-noexcept-function-type.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fexceptions -fcxx-exceptions -std=c++1z -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s
+
+// CHECK-LABEL: define {{.*}} @_Z11builtin_newm(
+// CHECK: call {{.*}} @_Znwm(
+void *builtin_new(unsigned long n) { return __builtin_operator_new(n); }
+
+// CHECK-LABEL: define {{.*}} @_Z14builtin_deletePv(
+// CHECK: call {{.*}} @_ZdlPv(
+void builtin_delete(void *p) { return __builtin_operator_delete(p); }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx2a-compare.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx2a-compare.cpp
new file mode 100644
index 0000000..ef6bb55
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cxx2a-compare.cpp
@@ -0,0 +1,188 @@
+// RUN: %clang_cc1 -std=c++2a -emit-llvm %s -o - -triple %itanium_abi_triple | \
+// RUN: FileCheck %s \
+// RUN: '-DWE="class.std::__1::weak_equality"' \
+// RUN: '-DSO="class.std::__1::strong_ordering"' \
+// RUN: '-DSE="class.std::__1::strong_equality"' \
+// RUN: '-DPO="class.std::__1::partial_ordering"' \
+// RUN: -DEQ=0 -DLT=-1 -DGT=1 -DUNORD=-127 -DNE=1
+
+#include "Inputs/std-compare.h"
+
+// Ensure we don't emit definitions for the global variables
+// since the builtins shouldn't ODR use them.
+// CHECK-NOT: constant %[[SO]]
+// CHECK-NOT: constant %[[SE]]
+// CHECK-NOT: constant %[[WE]]
+// CHECK-NOT: constant %[[PO]]
+
+// CHECK-LABEL: @_Z11test_signedii
+auto test_signed(int x, int y) {
+ // CHECK: %[[DEST:retval|agg.result]]
+ // CHECK: %cmp.lt = icmp slt i32 %0, %1
+ // CHECK: %sel.lt = select i1 %cmp.lt, i8 [[LT]], i8 [[GT]]
+ // CHECK: %cmp.eq = icmp eq i32 %0, %1
+ // CHECK: %sel.eq = select i1 %cmp.eq, i8 [[EQ]], i8 %sel.lt
+ // CHECK: %__value_ = getelementptr inbounds %[[SO]], %[[SO]]* %[[DEST]]
+ // CHECK: store i8 %sel.eq, i8* %__value_, align 1
+ // CHECK: ret
+ return x <=> y;
+}
+
+// CHECK-LABEL: @_Z13test_unsignedjj
+auto test_unsigned(unsigned x, unsigned y) {
+ // CHECK: %[[DEST:retval|agg.result]]
+ // CHECK: %cmp.lt = icmp ult i32 %0, %1
+ // CHECK: %sel.lt = select i1 %cmp.lt, i8 [[LT]], i8 [[GT]]
+ // CHECK: %cmp.eq = icmp eq i32 %0, %1
+ // CHECK: %sel.eq = select i1 %cmp.eq, i8 [[EQ]], i8 %sel.lt
+ // CHECK: %__value_ = getelementptr inbounds %[[SO]], %[[SO]]* %[[DEST]]
+ // CHECK: store i8 %sel.eq, i8* %__value_
+ // CHECK: ret
+ return x <=> y;
+}
+
+// CHECK-LABEL: @_Z10float_testdd
+auto float_test(double x, double y) {
+ // CHECK: %[[DEST:retval|agg.result]]
+ // CHECK: %cmp.eq = fcmp oeq double %0, %1
+ // CHECK: %sel.eq = select i1 %cmp.eq, i8 [[EQ]], i8 [[UNORD]]
+ // CHECK: %cmp.gt = fcmp ogt double %0, %1
+ // CHECK: %sel.gt = select i1 %cmp.gt, i8 [[GT]], i8 %sel.eq
+ // CHECK: %cmp.lt = fcmp olt double %0, %1
+ // CHECK: %sel.lt = select i1 %cmp.lt, i8 [[LT]], i8 %sel.gt
+ // CHECK: %__value_ = getelementptr inbounds %[[PO]], %[[PO]]* %[[DEST]]
+ // CHECK: store i8 %sel.lt, i8* %__value_
+ // CHECK: ret
+ return x <=> y;
+}
+
+// CHECK-LABEL: @_Z8ptr_testPiS_
+auto ptr_test(int *x, int *y) {
+ // CHECK: %[[DEST:retval|agg.result]]
+ // CHECK: %cmp.lt = icmp ult i32* %0, %1
+ // CHECK: %sel.lt = select i1 %cmp.lt, i8 [[LT]], i8 [[GT]]
+ // CHECK: %cmp.eq = icmp eq i32* %0, %1
+ // CHECK: %sel.eq = select i1 %cmp.eq, i8 [[EQ]], i8 %sel.lt
+ // CHECK: %__value_ = getelementptr inbounds %[[SO]], %[[SO]]* %[[DEST]]
+ // CHECK: store i8 %sel.eq, i8* %__value_, align 1
+ // CHECK: ret
+ return x <=> y;
+}
+
+struct MemPtr {};
+using MemPtrT = void (MemPtr::*)();
+using MemDataT = int(MemPtr::*);
+
+// CHECK-LABEL: @_Z12mem_ptr_testM6MemPtrFvvES1_
+auto mem_ptr_test(MemPtrT x, MemPtrT y) {
+ // CHECK: %[[DEST:retval|agg.result]]
+ // CHECK: %cmp.ptr = icmp eq [[TY:i[0-9]+]] %lhs.memptr.ptr, %rhs.memptr.ptr
+ // CHECK: %cmp.ptr.null = icmp eq [[TY]] %lhs.memptr.ptr, 0
+ // CHECK: %cmp.adj = icmp eq [[TY]] %lhs.memptr.adj, %rhs.memptr.adj
+ // CHECK: %[[OR:.*]] = or i1
+ // CHECK-SAME %cmp.adj
+ // CHECK: %memptr.eq = and i1 %cmp.ptr, %[[OR]]
+ // CHECK: %sel.eq = select i1 %memptr.eq, i8 [[EQ]], i8 [[NE]]
+ // CHECK: %__value_ = getelementptr inbounds %[[SE]], %[[SE]]* %[[DEST]]
+ // CHECK: store i8 %sel.eq, i8* %__value_, align 1
+ // CHECK: ret
+ return x <=> y;
+}
+
+// CHECK-LABEL: @_Z13mem_data_testM6MemPtriS0_
+auto mem_data_test(MemDataT x, MemDataT y) {
+ // CHECK: %[[DEST:retval|agg.result]]
+ // CHECK: %[[CMP:.*]] = icmp eq i{{[0-9]+}} %0, %1
+ // CHECK: %sel.eq = select i1 %[[CMP]], i8 [[EQ]], i8 [[NE]]
+ // CHECK: %__value_ = getelementptr inbounds %[[SE]], %[[SE]]* %[[DEST]]
+ // CHECK: store i8 %sel.eq, i8* %__value_, align 1
+ return x <=> y;
+}
+
+// CHECK-LABEL: @_Z13test_constantv
+auto test_constant() {
+ // CHECK: %[[DEST:retval|agg.result]]
+ // CHECK-NOT: icmp
+ // CHECK: %__value_ = getelementptr inbounds %[[SO]], %[[SO]]* %[[DEST]]
+ // CHECK-NEXT: store i8 -1, i8* %__value_
+ // CHECK: ret
+ const int x = 42;
+ const int y = 101;
+ return x <=> y;
+}
+
+// CHECK-LABEL: @_Z16test_nullptr_objPiDn
+auto test_nullptr_obj(int* x, decltype(nullptr) y) {
+ // CHECK: %[[DEST:retval|agg.result]]
+ // CHECK: %cmp.eq = icmp eq i32* %0, null
+ // CHECK: %sel.eq = select i1 %cmp.eq, i8 [[EQ]], i8 [[NE]]
+ // CHECK: %__value_ = getelementptr inbounds %[[SE]], %[[SE]]* %[[DEST]]
+ // CHECK: store i8 %sel.eq, i8* %__value_, align 1
+ return x <=> y;
+}
+
+// CHECK-LABEL: @_Z18unscoped_enum_testijxy
+void unscoped_enum_test(int i, unsigned u, long long l, unsigned long long ul) {
+ enum EnumA : int { A };
+ enum EnumB : unsigned { B };
+ // CHECK: %[[I:.*]] = load {{.*}} %i.addr
+ // CHECK: icmp slt i32 {{.*}} %[[I]]
+ (void)(A <=> i);
+
+ // CHECK: %[[U:.*]] = load {{.*}} %u.addr
+ // CHECK: icmp ult i32 {{.*}} %[[U]]
+ (void)(A <=> u);
+
+ // CHECK: %[[L:.*]] = load {{.*}} %l.addr
+ // CHECK: icmp slt i64 {{.*}} %[[L]]
+ (void)(A <=> l);
+
+ // CHECK: %[[U2:.*]] = load {{.*}} %u.addr
+ // CHECK: icmp ult i32 {{.*}} %[[U2]]
+ (void)(B <=> u);
+
+ // CHECK: %[[UL:.*]] = load {{.*}} %ul.addr
+ // CHECK: icmp ult i64 {{.*}} %[[UL]]
+ (void)(B <=> ul);
+}
+
+namespace NullptrTest {
+using nullptr_t = decltype(nullptr);
+
+// CHECK-LABEL: @_ZN11NullptrTest4testEDnDn(
+auto test(nullptr_t x, nullptr_t y) {
+ // CHECK: %[[DEST:retval|agg.result]]
+ // CHECK-NOT: select
+ // CHECK: %__value_ = getelementptr inbounds %[[SE]], %[[SE]]* %[[DEST]]
+ // CHECK-NEXT: store i8 [[EQ]], i8* %__value_
+ // CHECK: ret
+ return x <=> y;
+}
+} // namespace NullptrTest
+
+namespace ComplexTest {
+
+auto test_float(_Complex float x, _Complex float y) {
+ // CHECK: %[[DEST:retval|agg.result]]
+ // CHECK: %cmp.eq.r = fcmp oeq float %x.real, %y.real
+ // CHECK: %cmp.eq.i = fcmp oeq float %x.imag, %y.imag
+ // CHECK: %and.eq = and i1 %cmp.eq.r, %cmp.eq.i
+ // CHECK: %sel.eq = select i1 %and.eq, i8 [[EQ]], i8 [[NE]]
+ // CHECK: %__value_ = getelementptr inbounds %[[WE]], %[[WE]]* %[[DEST]]
+ // CHECK: store i8 %sel.eq, i8* %__value_, align 1
+ return x <=> y;
+}
+
+// CHECK-LABEL: @_ZN11ComplexTest8test_intECiS0_(
+auto test_int(_Complex int x, _Complex int y) {
+ // CHECK: %[[DEST:retval|agg.result]]
+ // CHECK: %cmp.eq.r = icmp eq i32 %x.real, %y.real
+ // CHECK: %cmp.eq.i = icmp eq i32 %x.imag, %y.imag
+ // CHECK: %and.eq = and i1 %cmp.eq.r, %cmp.eq.i
+ // CHECK: %sel.eq = select i1 %and.eq, i8 [[EQ]], i8 [[NE]]
+ // CHECK: %__value_ = getelementptr inbounds %[[SE]], %[[SE]]* %[[DEST]]
+ // CHECK: store i8 %sel.eq, i8* %__value_, align 1
+ return x <=> y;
+}
+
+} // namespace ComplexTest
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx2a-destroying-delete.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx2a-destroying-delete.cpp
new file mode 100644
index 0000000..60c5970
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cxx2a-destroying-delete.cpp
@@ -0,0 +1,161 @@
+// RUN: %clang_cc1 -std=c++2a -emit-llvm %s -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ITANIUM
+// RUN: %clang_cc1 -std=c++2a -emit-llvm %s -triple x86_64-windows -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-MSABI
+
+namespace std {
+ using size_t = decltype(sizeof(0));
+ enum class align_val_t : size_t;
+ struct destroying_delete_t {};
+}
+
+struct A {
+ void *data;
+ ~A();
+ void operator delete(A*, std::destroying_delete_t);
+};
+void delete_A(A *a) { delete a; }
+// CHECK-LABEL: define {{.*}}delete_A
+// CHECK: %[[a:.*]] = load
+// CHECK: icmp eq %{{.*}} %[[a]], null
+// CHECK: br i1
+//
+// Ensure that we call the destroying delete and not the destructor.
+// CHECK-NOT: call
+// CHECK-ITANIUM: call void @_ZN1AdlEPS_St19destroying_delete_t(%{{.*}}* %[[a]])
+// CHECK-MSABI: call void @"??3A@@SAXPEAU0@Udestroying_delete_t@std@@@Z"(%{{.*}}* %[[a]], i8
+// CHECK-NOT: call
+// CHECK: }
+
+struct B {
+ virtual ~B();
+ void operator delete(B*, std::destroying_delete_t);
+};
+void delete_B(B *b) { delete b; }
+// CHECK-LABEL: define {{.*}}delete_B
+// CHECK: %[[b:.*]] = load
+// CHECK: icmp eq %{{.*}} %[[b]], null
+// CHECK: br i1
+//
+// Ensure that we call the virtual destructor and not the operator delete.
+// CHECK-NOT: call
+// CHECK: %[[VTABLE:.*]] = load
+// CHECK: %[[DTOR:.*]] = load
+// CHECK: call {{void|i8\*}} %[[DTOR]](%{{.*}}* %[[b]]
+// CHECK-MSABI-SAME: , i32 1)
+// CHECK-NOT: call
+// CHECK: }
+
+struct Padding {
+ virtual void f();
+};
+
+struct C : Padding, A {};
+void delete_C(C *c) { delete c; }
+// Check that we perform a derived-to-base conversion on the parameter to 'operator delete'.
+// CHECK-LABEL: define {{.*}}delete_C
+// CHECK: %[[c:.*]] = load
+// CHECK: icmp eq %{{.*}} %[[c]], null
+// CHECK: br i1
+//
+// CHECK: %[[base:.*]] = getelementptr {{.*}}, i64 8
+// CHECK: %[[castbase:.*]] = bitcast {{.*}} %[[base]]
+//
+// CHECK: %[[a:.*]] = phi {{.*}} %[[castbase]]
+// CHECK: icmp eq %{{.*}} %[[a]], null
+// CHECK: br i1
+//
+// CHECK-NOT: call
+// CHECK-ITANIUM: call void @_ZN1AdlEPS_St19destroying_delete_t(%{{.*}}* %[[a]])
+// CHECK-MSABI: call void @"??3A@@SAXPEAU0@Udestroying_delete_t@std@@@Z"(%{{.*}}* %[[a]], i8
+// CHECK-NOT: call
+// CHECK: }
+
+struct VDel { virtual ~VDel(); };
+struct D : Padding, VDel, B {};
+void delete_D(D *d) { delete d; }
+// CHECK-LABEL: define {{.*}}delete_D
+// CHECK: %[[d:.*]] = load
+// CHECK: icmp eq %{{.*}} %[[d]], null
+// CHECK: br i1
+//
+// CHECK-NOT: call
+// For MS, we don't add a new vtable slot to the primary vtable for the virtual
+// destructor. Instead we cast to the VDel base class.
+// CHECK-MSABI: bitcast {{.*}} %[[d]]
+// CHECK-MSABI-NEXT: getelementptr {{.*}}, i64 8
+// CHECK-MSABI-NEXT: %[[d:.*]] = bitcast i8*
+//
+// CHECK: %[[VTABLE:.*]] = load
+// CHECK: %[[DTOR:.*]] = load
+//
+// CHECK: call {{void|i8\*}} %[[DTOR]](%{{.*}}* %[[d]]
+// CHECK-MSABI-SAME: , i32 1)
+// CHECK-NOT: call
+// CHECK: }
+
+struct E { void *data; };
+struct F { void operator delete(F *, std::destroying_delete_t, std::size_t, std::align_val_t); void *data; };
+struct alignas(16) G : E, F { void *data; };
+
+void delete_G(G *g) { delete g; }
+// CHECK-LABEL: define {{.*}}delete_G
+// CHECK-NOT: call
+// CHECK-ITANIUM: call void @_ZN1FdlEPS_St19destroying_delete_tmSt11align_val_t(%{{.*}}* %[[a]], i64 32, i64 16)
+// CHECK-MSABI: call void @"??3F@@SAXPEAU0@Udestroying_delete_t@std@@_KW4align_val_t@2@@Z"(%{{.*}}* %[[a]], i8 {{[^,]*}}, i64 32, i64 16)
+// CHECK-NOT: call
+// CHECK: }
+
+void call_in_dtor();
+
+struct H : G { virtual ~H(); } h;
+H::~H() { call_in_dtor(); }
+// CHECK-ITANIUM-LABEL: define void @_ZN1HD0Ev(
+// CHECK-ITANIUM-NOT: call
+// CHECK-ITANIUM: getelementptr {{.*}}, i64 24
+// CHECK-ITANIUM-NOT: call
+// CHECK-ITANIUM: call void @_ZN1FdlEPS_St19destroying_delete_tmSt11align_val_t({{.*}}, i64 48, i64 16)
+// CHECK-ITANIUM-NOT: call
+// CHECK-ITANIUM: }
+
+// CHECK-MSABI: define {{.*}} @"??_GH@@UEAAPEAXI@Z"(
+// CHECK-MSABI-NOT: call{{ }}
+// CHECK-MSABI: load i32
+// CHECK-MSABI: icmp eq i32 {{.*}}, 0
+// CHECK-MSABI: br i1
+//
+// CHECK-MSABI-NOT: call{{ }}
+// CHECK-MSABI: getelementptr {{.*}}, i64 24
+// CHECK-MSABI-NOT: call{{ }}
+// CHECK-MSABI: call void @"??3F@@SAXPEAU0@Udestroying_delete_t@std@@_KW4align_val_t@2@@Z"({{.*}}, i64 48, i64 16)
+// CHECK-MSABI: br label %[[RETURN:.*]]
+//
+// CHECK-MSABI: call void @"??1H@@UEAA@XZ"(
+// CHECK-MSABI: br label %[[RETURN]]
+//
+// CHECK-MSABI: }
+
+struct I : H { virtual ~I(); alignas(32) char buffer[32]; } i;
+I::~I() { call_in_dtor(); }
+// CHECK-ITANIUM-LABEL: define void @_ZN1ID0Ev(
+// CHECK-ITANIUM-NOT: call
+// CHECK-ITANIUM: getelementptr {{.*}}, i64 24
+// CHECK-ITANIUM-NOT: call
+// CHECK-ITANIUM: call void @_ZN1FdlEPS_St19destroying_delete_tmSt11align_val_t({{.*}}, i64 96, i64 32)
+// CHECK-ITANIUM-NOT: call
+// CHECK-ITANIUM: }
+
+// CHECK-MSABI: define {{.*}} @"??_GI@@UEAAPEAXI@Z"(
+// CHECK-MSABI-NOT: call{{ }}
+// CHECK-MSABI: load i32
+// CHECK-MSABI: icmp eq i32 {{.*}}, 0
+// CHECK-MSABI: br i1
+//
+// CHECK-MSABI-NOT: call{{ }}
+// CHECK-MSABI: getelementptr {{.*}}, i64 24
+// CHECK-MSABI-NOT: call{{ }}
+// CHECK-MSABI: call void @"??3F@@SAXPEAU0@Udestroying_delete_t@std@@_KW4align_val_t@2@@Z"({{.*}}, i64 96, i64 32)
+// CHECK-MSABI: br label %[[RETURN:.*]]
+//
+// CHECK-MSABI: call void @"??1I@@UEAA@XZ"(
+// CHECK-MSABI: br label %[[RETURN]]
+//
+// CHECK-MSABI: }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx2a-init-statement.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx2a-init-statement.cpp
new file mode 100644
index 0000000..2d45c85
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cxx2a-init-statement.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -std=c++2a -triple x86_64-apple-macosx10.7.0 -emit-llvm -o - %s -w | FileCheck %s
+
+// CHECK: @__const._Z1fv.arr = private unnamed_addr constant [3 x i32] [i32 1, i32 2, i32 3], align 4
+
+void f() {
+ // CHECK: %[[ARR:.*]] = alloca [3 x i32], align 4
+ // CHECK: call void @llvm.memcpy{{.*}}({{.*}} @__const._Z1fv.arr
+ for (int arr[3] = {1, 2, 3}; int a : arr)
+ ;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/cxx2a-three-way-comparison.cpp b/src/llvm-project/clang/test/CodeGenCXX/cxx2a-three-way-comparison.cpp
new file mode 100644
index 0000000..fd72d4a
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/cxx2a-three-way-comparison.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -std=c++2a -emit-llvm %s -o - -triple %itanium_abi_triple | FileCheck %s --check-prefix=ITANIUM
+// RUN: not %clang_cc1 -std=c++2a -emit-llvm %s -o - -triple %ms_abi_triple 2>&1 | FileCheck %s --check-prefix=MSABI
+// RUN: not %clang_cc1 -std=c++2a -emit-llvm %s -o - -triple %itanium_abi_triple -DBUILTIN 2>&1 | FileCheck %s --check-prefix=BUILTIN
+// MSABI: cannot mangle this three-way comparison operator yet
+
+struct A {
+ void operator<=>(int);
+};
+
+// ITANIUM: define {{.*}}@_ZN1AssEi(
+void A::operator<=>(int) {}
+
+// ITANIUM: define {{.*}}@_Zssi1A(
+void operator<=>(int, A) {}
+
+int operator<=>(A, A);
+
+// ITANIUM: define {{.*}}_Z1f1A(
+int f(A a) {
+ // ITANIUM: %[[RET:.*]] = call {{.*}}_Zss1AS_(
+ // ITANIUM: ret i32 %[[RET]]
+ return a <=> a;
+}
+
+#ifdef BUILTIN
+void builtin(int a) {
+ a <=> a; // BUILTIN: cannot compile this scalar expression yet
+}
+#endif
diff --git a/src/llvm-project/clang/test/CodeGenCXX/dbg-info-all-calls-described.cpp b/src/llvm-project/clang/test/CodeGenCXX/dbg-info-all-calls-described.cpp
new file mode 100644
index 0000000..547c2707
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/dbg-info-all-calls-described.cpp
@@ -0,0 +1,61 @@
+// Test that call site debug info is (un)supported in various configurations.
+
+// Supported: DWARF5, -O1, standalone DI
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple %s -o - \
+// RUN: -O1 -disable-llvm-passes \
+// RUN: -debug-info-kind=standalone -dwarf-version=5 \
+// RUN: | FileCheck %s -check-prefix=HAS-ATTR \
+// RUN: -implicit-check-not=DISubprogram -implicit-check-not=DIFlagAllCallsDescribed
+
+// Supported: DWARF4 + LLDB tuning, -O1, limited DI
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple %s -o - \
+// RUN: -O1 -disable-llvm-passes \
+// RUN: -debugger-tuning=lldb \
+// RUN: -debug-info-kind=standalone -dwarf-version=4 \
+// RUN: | FileCheck %s -check-prefix=HAS-ATTR \
+// RUN: -implicit-check-not=DISubprogram -implicit-check-not=DIFlagAllCallsDescribed
+
+// Supported: DWARF4 + LLDB tuning, -O1, line-tables only DI
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple %s -o - \
+// RUN: -O1 -disable-llvm-passes \
+// RUN: -debugger-tuning=lldb \
+// RUN: -debug-info-kind=line-tables-only -dwarf-version=4 \
+// RUN: | FileCheck %s -check-prefix=LINE-TABLES-ONLY
+
+// Unsupported: -O0
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple %s -o - \
+// RUN: -O0 \
+// RUN: -debug-info-kind=standalone -dwarf-version=5 \
+// RUN: | FileCheck %s -check-prefix=NO-ATTR
+
+// Unsupported: DWARF4
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple %s -o - \
+// RUN: -O1 -disable-llvm-passes \
+// RUN: -debug-info-kind=standalone -dwarf-version=4 \
+// RUN: | FileCheck %s -check-prefix=NO-ATTR
+
+// NO-ATTR-NOT: FlagAllCallsDescribed
+
+// HAS-ATTR-DAG: DISubprogram(name: "declaration2", {{.*}}, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition
+// HAS-ATTR-DAG: DISubprogram(name: "struct1", {{.*}}, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized)
+// HAS-ATTR-DAG: DISubprogram(name: "struct1", {{.*}}, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition
+// HAS-ATTR-DAG: DISubprogram(name: "method1", {{.*}}, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition
+// HAS-ATTR-DAG: DISubprogram(name: "force_irgen", {{.*}}, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition
+
+// LINE-TABLES-ONLY: DISubprogram(name: "force_irgen", {{.*}}, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition
+
+void declaration1();
+
+void declaration2();
+
+void declaration2() {}
+
+struct struct1 {
+ struct1() {}
+ void method1() {}
+};
+
+void __attribute__((optnone)) force_irgen() {
+ declaration1();
+ struct1().method1();
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-access.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-access.cpp
new file mode 100644
index 0000000..0759ee1
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-access.cpp
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -triple %itanium_abi_triple %s -o - | FileCheck %s
+// Test the various accessibility flags in the debug info.
+struct A {
+ // CHECK: ![[A:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "A",
+
+ // CHECK-DAG: !DISubprogram(name: "pub_default",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagPrototyped,
+ void pub_default();
+ // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "pub_default_static",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagStaticMember)
+ static int pub_default_static;
+};
+
+
+// CHECK: !DIDerivedType(tag: DW_TAG_inheritance,{{.*}} baseType: ![[A]],{{.*}} flags: DIFlagPublic, extraData: i32 0)
+class B : public A {
+public:
+ // CHECK-DAG: !DISubprogram(name: "pub",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagPublic | DIFlagPrototyped,
+ void pub();
+ // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "public_static",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagPublic | DIFlagStaticMember)
+ static int public_static;
+protected:
+ // CHECK: !DISubprogram(name: "prot",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagProtected | DIFlagPrototyped,
+ void prot();
+private:
+ // CHECK: !DISubprogram(name: "priv_default",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagPrototyped,
+ void priv_default();
+};
+
+union U {
+ // CHECK-DAG: !DISubprogram(name: "union_pub_default",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagPrototyped,
+ void union_pub_default();
+private:
+ // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "union_priv",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagPrivate)
+ int union_priv;
+};
+
+
+// CHECK: !DISubprogram(name: "free",
+// CHECK-SAME: flags: DIFlagPrototyped,
+// CHECK-SAME: spFlags: DISPFlagDefinition
+void free() {}
+
+U u;
+A a;
+B b;
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-alias.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-alias.cpp
new file mode 100644
index 0000000..8c3f844
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-alias.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang -g -std=c++11 -S -emit-llvm %s -o - | FileCheck %s
+
+template<typename T>
+struct foo {
+};
+namespace x {
+// splitting these over multiple lines to make sure the right token is used for
+// the location
+template<typename T>
+using
+# 42
+bar
+= foo<T*>;
+}
+
+// CHECK: !DIGlobalVariable(name: "bi",{{.*}} type: [[BINT:![0-9]+]]
+x::bar<int> bi;
+// CHECK: !DIGlobalVariable(name: "bf",{{.*}} type: [[BFLOAT:![0-9]+]]
+// CHECK: [[BFLOAT]] = !DIDerivedType(tag: DW_TAG_typedef, name: "bar<float>"
+x::bar<float> bf;
+
+using
+// CHECK: !DIGlobalVariable(name: "n",{{.*}} type: [[NARF:![0-9]+]]
+# 142
+narf // CHECK: [[NARF]] = !DIDerivedType(tag: DW_TAG_typedef, name: "narf"
+// CHECK-SAME: line: 142
+= int;
+narf n;
+
+template <typename T>
+using tv = void;
+// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "tv<int>"
+tv<int> *tvp;
+
+using v = void;
+// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "v"
+v *vp;
+
+// CHECK: [[BINT]] = !DIDerivedType(tag: DW_TAG_typedef, name: "bar<int>"
+// CHECK-SAME: line: 42,
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-anon-namespace.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-anon-namespace.cpp
new file mode 100644
index 0000000..56c8528
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-anon-namespace.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -dwarf-explicit-import -O0 %s -o - | FileCheck --check-prefix=IMPORT %s
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -O0 %s -o - | FileCheck --check-prefix=NOIMPORT %s
+
+namespace
+{
+ int a = 5;
+}
+int *b = &a;
+
+namespace
+{
+ namespace {
+ int a1 = 5;
+ }
+ int a2 = 7;
+}
+int *b1 = &a1;
+int *b2 = &a2;
+
+// IMPORT: [[NS:![0-9]+]] = !DINamespace
+// IMPORT: [[CU:![0-9]+]] = distinct !DICompileUnit
+// IMPORT: [[NS2:![0-9]+]] = !DINamespace
+// IMPORT: !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[CU]], entity: [[NS]], file: {{![0-9]+}})
+// IMPORT: !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[NS]], entity: [[NS2]], file: {{![0-9]+}}, line: {{[0-9]+}})
+// NOIMPORT-NOT: !DIImportedEntity
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-anon-union-vars.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-anon-union-vars.cpp
new file mode 100644
index 0000000..61b3c7c
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-anon-union-vars.cpp
@@ -0,0 +1,63 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -triple x86_64-linux-gnu %s -o - | FileCheck %s
+
+// Make sure that we emit a global variable for each of the members of the
+// anonymous union.
+
+static union {
+ int c;
+ int d;
+ union {
+ int a;
+ };
+ struct {
+ int b;
+ };
+};
+
+int test_it() {
+ c = 1;
+ d = 2;
+ a = 4;
+ return (c == 1);
+}
+
+void foo() {
+ union {
+ int i;
+ char c;
+ };
+ i = 8;
+}
+
+// A funky reinterpret cast idiom that we used to crash on.
+template <class T>
+unsigned char *buildBytes(const T v) {
+ static union {
+ unsigned char result[sizeof(T)];
+ T value;
+ };
+ value = v;
+ return result;
+}
+
+void instantiate(int x) {
+ buildBytes(x);
+}
+
+// CHECK: !DIGlobalVariable(name: "c",{{.*}} file: [[FILE:.*]], line: 6,{{.*}} isLocal: true, isDefinition: true
+// CHECK: !DIGlobalVariable(name: "d",{{.*}} file: [[FILE]], line: 6,{{.*}} isLocal: true, isDefinition: true
+// CHECK: [[FILE]] = !DIFile(filename: "{{.*}}debug-info-anon-union-vars.cpp",
+// CHECK: !DIGlobalVariable(name: "a",{{.*}} file: [[FILE]], line: 6,{{.*}} isLocal: true, isDefinition: true
+// CHECK: !DIGlobalVariable(name: "b",{{.*}} file: [[FILE]], line: 6,{{.*}} isLocal: true, isDefinition: true
+// CHECK: !DIGlobalVariable(name: "result", {{.*}} isLocal: false, isDefinition: true
+// CHECK: !DIGlobalVariable(name: "value", {{.*}} isLocal: false, isDefinition: true
+// CHECK: !DILocalVariable(name: "i", {{.*}}, flags: DIFlagArtificial
+// CHECK: !DILocalVariable(name: "c", {{.*}}, flags: DIFlagArtificial
+// CHECK: !DILocalVariable(
+// CHECK-NOT: name:
+// CHECK: type: ![[UNION:[0-9]+]]
+// CHECK: ![[UNION]] = distinct !DICompositeType(tag: DW_TAG_union_type,
+// CHECK-NOT: name:
+// CHECK: elements
+// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "i", scope: ![[UNION]],
+// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "c", scope: ![[UNION]],
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-artificial-arg.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-artificial-arg.cpp
new file mode 100644
index 0000000..a0cf131
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-artificial-arg.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -triple x86_64-apple-darwin %s -o - | FileCheck %s
+
+template<class X> class B {
+public:
+ explicit B(X* p = 0);
+};
+
+class A
+{
+public:
+ A(int value) : m_a_value(value) {};
+ A(int value, A* client_A) : m_a_value (value), m_client_A (client_A) {}
+
+ virtual ~A() {}
+
+private:
+ int m_a_value;
+ B<A> m_client_A;
+};
+
+int main(int argc, char **argv) {
+ A reallyA (500);
+}
+
+// CHECK: ![[CLASSTYPE:.*]] = distinct !DICompositeType(tag: DW_TAG_class_type, name: "A",
+// CHECK-SAME: identifier: "_ZTS1A"
+// CHECK: ![[ARTARG:.*]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[CLASSTYPE]],{{.*}} DIFlagArtificial
+// CHECK: !DISubprogram(name: "A", scope: ![[CLASSTYPE]]
+// CHECK-SAME: line: 12
+// CHECK-SAME: DIFlagPublic
+// CHECK: !DISubroutineType(types: [[FUNCTYPE:![0-9]*]])
+// CHECK: [[FUNCTYPE]] = !{null, ![[ARTARG]], !{{.*}}, !{{.*}}}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-blocks.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-blocks.cpp
new file mode 100644
index 0000000..7eea3ce
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-blocks.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 %s -debug-info-kind=line-tables-only -fblocks -S -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -debug-info-kind=line-directives-only -fblocks -S -emit-llvm -o - | FileCheck %s
+
+struct A {
+ A();
+ A(const A &);
+ ~A();
+};
+
+void test() {
+ __block A a;
+ ^{ (void)a; };
+}
+
+// CHECK: !DISubprogram(name: "__Block_byref_object_copy_",
+// CHECK-SAME: line: 11,
+// CHECK-SAME: DISPFlagLocalToUnit | DISPFlagDefinition
+// CHECK: !DISubprogram(name: "__Block_byref_object_dispose_",
+// CHECK-SAME: line: 11,
+// CHECK-SAME: DISPFlagLocalToUnit | DISPFlagDefinition
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-byval.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-byval.cpp
new file mode 100644
index 0000000..38f803d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-byval.cpp
@@ -0,0 +1,32 @@
+// FIXME: Check IR rather than asm, then triple is not needed.
+// RUN: %clang --target=%itanium_abi_triple -g -S %s -o - | FileCheck %s
+// Test to check presence of debug info for byval parameter.
+// Radar 8350436.
+class DAG {
+public:
+ int i;
+ int j;
+};
+
+class EVT {
+public:
+ int a;
+ int b;
+ int c;
+};
+
+class VAL {
+public:
+ int x;
+ int y;
+};
+void foo(EVT e);
+EVT bar();
+
+void get(int *i, unsigned dl, VAL v, VAL *p, unsigned n, EVT missing_arg) {
+//CHECK: .{{asciz|string}} "missing_arg"
+ EVT e = bar();
+ if (dl == n)
+ foo(missing_arg);
+}
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-calling-conventions.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-calling-conventions.cpp
new file mode 100644
index 0000000..db7fbd2
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-calling-conventions.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 %s -triple=i686-pc-windows-msvc -debug-info-kind=limited -emit-llvm -o - | FileCheck %s
+
+struct A {
+ void thiscallcc();
+};
+void A::thiscallcc() {}
+
+// CHECK: !DISubprogram(name: "thiscallcc", {{.*}} type: ![[thiscallty:[^,]*]], {{.*}})
+// CHECK: ![[thiscallty]] = !DISubroutineType(cc: DW_CC_BORLAND_thiscall, types: ![[thisargs:[^,)]*]])
+// CHECK: ![[thisargs]] = !{null, ![[thisptrty:[^,}]*]]}
+// CHECK: ![[thisptrty]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !{{.*}}, size: 32, flags: DIFlagArtificial | DIFlagObjectPointer)
+
+void cdeclcc() {}
+void __fastcall fastcallcc() {}
+void __stdcall stdcallcc() {}
+void __vectorcall vectorcallcc() {}
+
+// CHECK: !DISubprogram(name: "cdeclcc", {{.*}} type: ![[cdeclty:[^,]*]], {{.*}})
+// CHECK: ![[cdeclty]] = !DISubroutineType(types: ![[noargs:[^,)]*]])
+// CHECK: ![[noargs]] = !{null}
+// CHECK: !DISubprogram(name: "fastcallcc", {{.*}} type: ![[fastcallty:[^,]*]], {{.*}})
+// CHECK: ![[fastcallty]] = !DISubroutineType(cc: DW_CC_BORLAND_msfastcall, types: ![[noargs]])
+// CHECK: !DISubprogram(name: "stdcallcc", {{.*}} type: ![[stdcallty:[^,]*]], {{.*}})
+// CHECK: ![[stdcallty]] = !DISubroutineType(cc: DW_CC_BORLAND_stdcall, types: ![[noargs]])
+// CHECK: !DISubprogram(name: "vectorcallcc", {{.*}} type: ![[vectorcallty:[^,]*]], {{.*}})
+// CHECK: ![[vectorcallty]] = !DISubroutineType(cc: DW_CC_LLVM_vectorcall, types: ![[noargs]])
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-char16.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-char16.cpp
new file mode 100644
index 0000000..83ffea6
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-char16.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -std=c++11 -debug-info-kind=limited %s -o -| FileCheck %s
+
+// 16 is DW_ATE_UTF (0x10) encoding attribute.
+char16_t char_a = u'h';
+
+// CHECK: !{{.*}} = !DIBasicType(name: "char16_t"
+// CHECK-SAME: encoding: DW_ATE_UTF)
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-class-limited-plugin.test b/src/llvm-project/clang/test/CodeGenCXX/debug-info-class-limited-plugin.test
new file mode 100644
index 0000000..17248d5
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-class-limited-plugin.test
@@ -0,0 +1,2 @@
+RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -o - -load %llvmshlibdir/PrintFunctionNames%pluginext -add-plugin print-fns %S/Inputs/debug-info-class-limited.cpp 2>&1 | FileCheck %S/Inputs/debug-info-class-limited.cpp
+REQUIRES: plugins, examples
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-class-limited.test b/src/llvm-project/clang/test/CodeGenCXX/debug-info-class-limited.test
new file mode 100644
index 0000000..c2e3328
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-class-limited.test
@@ -0,0 +1 @@
+RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited %S/Inputs/debug-info-class-limited.cpp -o - | FileCheck %S/Inputs/debug-info-class-limited.cpp
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-class-nolimit.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-class-nolimit.cpp
new file mode 100644
index 0000000..b184b9e
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-class-nolimit.cpp
@@ -0,0 +1,54 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -debug-info-kind=standalone -o - -emit-llvm %s | FileCheck %s
+
+// We had a bug in -fstandalone-debug where UnicodeString would not be completed
+// when it was required to be complete. This originally manifested as an
+// assertion in CodeView emission on Windows with some dllexport stuff, but it's
+// more general than that.
+
+struct UnicodeString;
+UnicodeString *force_fwd_decl;
+struct UnicodeString {
+private:
+ virtual ~UnicodeString();
+};
+struct UseCompleteType {
+ UseCompleteType();
+ ~UseCompleteType();
+ UnicodeString currencySpcAfterSym[1];
+};
+UseCompleteType require_complete;
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "UnicodeString"
+// CHECK-NOT: DIFlagFwdDecl
+// CHECK-SAME: ){{$}}
+
+namespace rdar14101097_1 { // see also PR16214
+// Check that we emit debug info for the definition of a struct if the
+// definition is available, even if it's used via a pointer wrapped in a
+// typedef.
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "foo"
+// CHECK-NOT: DIFlagFwdDecl
+// CHECK-SAME: ){{$}}
+struct foo {
+};
+
+typedef foo *foop;
+
+void bar() {
+ foop f;
+}
+}
+
+namespace rdar14101097_2 {
+// As above, except trickier because we first encounter only a declaration of
+// the type and no debug-info related use after we see the definition of the
+// type.
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "foo"
+// CHECK-NOT: DIFlagFwdDecl
+// CHECK-SAME: ){{$}}
+struct foo;
+void bar() {
+ foo *f;
+}
+struct foo {
+};
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-class-optzns.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-class-optzns.cpp
new file mode 100644
index 0000000..d58510b
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-class-optzns.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple x86_64-unknown_unknown -emit-llvm -debug-info-kind=limited %s -O1 -o - | FileCheck %s
+
+// Ensure class definitions are not emitted to debug info just because the
+// vtable is emitted for optimization purposes (as available_externally). The
+// class definition debug info should only go where the vtable is actually
+// emitted into the object file.
+
+// CHECK: @_ZTV3foo = available_externally
+
+// Verify that this doesn't involve querying for the vtable of types that aren't
+// dynamic (that would cause an assertion in the case below)
+
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "bar<int>"
+template <typename> struct bar {};
+extern template struct bar<int>;
+bar<int> *p1;
+bar<int> a;
+
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "foo"
+// CHECK-SAME: DIFlagFwdDecl
+
+struct foo {
+ virtual void f();
+};
+
+foo f;
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-class.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-class.cpp
new file mode 100644
index 0000000..e06ef8d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-class.cpp
@@ -0,0 +1,159 @@
+struct foo;
+void func(foo *f) {
+}
+class bar;
+void func(bar *f) {
+}
+union baz;
+void func(baz *f) {
+}
+
+class B {
+public:
+ virtual ~B();
+};
+
+B::~B() {
+}
+
+struct C {
+ static int s;
+ virtual ~C();
+};
+
+C::~C() {
+}
+
+struct D {
+ D();
+ virtual ~D();
+ void func() {
+ }
+};
+
+struct E {
+ E();
+ virtual ~E();
+ virtual void func() {
+ }
+};
+
+struct F {
+ struct inner {
+ };
+ static const int i = 2;
+ virtual ~F();
+};
+
+struct G {
+ virtual void func();
+ struct inner {
+ int j;
+ };
+};
+
+struct H {};
+struct I : virtual H {};
+struct J : I {};
+J j;
+
+struct A {
+ int one;
+ static const int HdrSize = 52;
+ int two;
+ A() {
+ int x = 1;
+ }
+};
+
+void f1() {
+ D x;
+ x.func();
+ E y;
+ int i = F::i;
+ F::inner z;
+}
+
+int main(int argc, char **argv) {
+ B b;
+ G::inner c_i;
+ if (argc) {
+ A a;
+ }
+ return 0;
+}
+
+// RUN: %clang_cc1 -triple x86_64-unknown_unknown -emit-llvm -debug-info-kind=limited -fexceptions -std=c++98 %s -o - | FileCheck -check-prefix=CHECK98 %s
+// RUN: %clang_cc1 -triple i686-cygwin -emit-llvm -debug-info-kind=limited -fexceptions -std=c++98 %s -o - | FileCheck -check-prefix=CHECK98 %s
+// RUN: %clang_cc1 -triple armv7l-unknown-linux-gnueabihf -emit-llvm -debug-info-kind=limited -fexceptions -std=c++98 %s -o - | FileCheck -check-prefix=CHECK98 %s
+// RUN: %clang_cc1 -triple x86_64-unknown_unknown -emit-llvm -debug-info-kind=limited -fexceptions -std=c++11 %s -o - | FileCheck -check-prefix=CHECK11 %s
+// RUN: %clang_cc1 -triple i686-cygwin -emit-llvm -debug-info-kind=limited -fexceptions -std=c++11 %s -o - | FileCheck -check-prefix=CHECK11 %s
+// RUN: %clang_cc1 -triple armv7l-unknown-linux-gnueabihf -emit-llvm -debug-info-kind=limited -fexceptions -std=c++11 %s -o - | FileCheck -check-prefix=CHECK11 %s
+
+// CHECK98: invoke {{.+}} @_ZN1BD1Ev(%class.B* %b)
+// CHECK98-NEXT: unwind label %{{.+}}, !dbg ![[EXCEPTLOC:.*]]
+// CHECK11: call {{.+}} @_ZN1BD1Ev(%class.B* %b){{.*}}, !dbg ![[EXCEPTLOC:.*]]
+
+// CHECK: store i32 0, i32* %{{.+}}, !dbg ![[RETLOC:.*]]
+
+// CHECK: [[F:![0-9]*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "F"
+// CHECK-SAME: DIFlagFwdDecl
+// CHECK-SAME: identifier: "_ZTS1F"
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "I"
+// CHECK-NOT: DIFlagFwdDecl
+// CHECK-SAME: ){{$}}
+
+// CHECK: ![[INT:[0-9]+]] = !DIBasicType(name: "int"
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "foo"
+// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "bar"
+// CHECK: !DICompositeType(tag: DW_TAG_union_type, name: "baz"
+// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "B"
+// CHECK-NOT: DIFlagFwdDecl
+// CHECK-SAME: ){{$}}
+// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "_vptr$B",
+// CHECK-SAME: DIFlagArtificial
+
+// CHECK: [[C:![0-9]*]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "C",
+// CHECK-NOT: DIFlagFwdDecl
+// CHECK-SAME: elements: [[C_MEM:![0-9]*]]
+// CHECK-SAME: vtableHolder: [[C]]
+// CHECK-SAME: identifier: "_ZTS1C"
+// CHECK: [[C_MEM]] = !{[[C_VPTR:![0-9]*]], [[C_S:![0-9]*]], [[C_DTOR:![0-9]*]]}
+// CHECK: [[C_VPTR]] = !DIDerivedType(tag: DW_TAG_member, name: "_vptr$C"
+// CHECK-SAME: DIFlagArtificial
+// CHECK: [[C_S]] = !DIDerivedType(tag: DW_TAG_member, name: "s"
+// CHECK-SAME: baseType: ![[INT]]
+// CHECK-SAME: DIFlagStaticMember
+// CHECK: [[C_DTOR]] = !DISubprogram(name: "~C"
+
+// CHECK: [[D:![0-9]+]] = !DICompositeType(tag: DW_TAG_structure_type, name: "D"
+// CHECK-NOT: size:
+// CHECK-SAME: DIFlagFwdDecl
+// CHECK-SAME: identifier: "_ZTS1D"
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "E"
+// CHECK-SAME: DIFlagFwdDecl
+// CHECK-SAME: identifier: "_ZTS1E"
+
+// CHECK: !DISubprogram(name: "func",{{.*}} scope: [[D]]
+// CHECK-SAME: isDefinition: true
+// CHECK-SAME: declaration: [[D_FUNC_DECL:![0-9]*]]
+// CHECK: [[D_FUNC_DECL]] = !DISubprogram(name: "func",{{.*}} scope: [[D]]
+// CHECK-SAME: isDefinition: false
+
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "inner",{{.*}} line: 50
+// CHECK-NOT: DIFlagFwdDecl
+// CHECK-SAME: elements: [[G_INNER_MEM:![0-9]*]]
+// CHECK-SAME: identifier: "_ZTSN1G5innerE"
+
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "G"
+// CHECK-SAME: DIFlagFwdDecl
+// CHECK-SAME: identifier: "_ZTS1G"
+// CHECK: [[G_INNER_MEM]] = !{[[G_INNER_I:![0-9]*]]}
+// CHECK: [[G_INNER_I]] = !DIDerivedType(tag: DW_TAG_member, name: "j"
+// CHECK-SAME: baseType: ![[INT]]
+
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "A"
+// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "HdrSize"
+//
+// CHECK: ![[EXCEPTLOC]] = !DILocation(line: 84,
+// CHECK: ![[RETLOC]] = !DILocation(line: 83,
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-codeview-display-name.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-codeview-display-name.cpp
new file mode 100644
index 0000000..17049d5
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-codeview-display-name.cpp
@@ -0,0 +1,98 @@
+// RUN: %clang_cc1 -fblocks -debug-info-kind=limited -gcodeview -emit-llvm %s \
+// RUN: -o - -triple=x86_64-pc-win32 -std=c++98 | \
+// RUN: grep 'DISubprogram\|DICompositeType' | sed -e 's/.*name: "\([^"]*\)".*/"\1"/' | \
+// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=UNQUAL
+// RUN: %clang_cc1 -fblocks -debug-info-kind=line-tables-only -gcodeview -emit-llvm %s \
+// RUN: -o - -triple=x86_64-pc-win32 -std=c++98 | \
+// RUN: grep 'DISubprogram' | sed -e 's/.*name: "\([^"]*\)".*/"\1"/' | \
+// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=QUAL
+
+void freefunc() { }
+// CHECK-DAG: "freefunc"
+
+namespace N {
+ int b() { return 0; }
+// UNQUAL-DAG: "b"
+// QUAL-DAG: "N::b"
+ namespace { void func() { } }
+// UNQUAL-DAG: "func"
+// QUAL-DAG: "N::`anonymous namespace'::func"
+}
+
+void _c(void) {
+ N::func();
+}
+// CHECK-DAG: "_c"
+
+struct foo {
+ int operator+(int);
+ foo(){}
+// UNQUAL-DAG: "foo"
+// QUAL-DAG: "foo::foo"
+
+ ~foo(){}
+// UNQUAL-DAG: "~foo"
+// QUAL-DAG: "foo::~foo"
+
+ foo(int i){}
+// UNQUAL-DAG: "foo"
+// QUAL-DAG: "foo::foo"
+
+ foo(char *q){}
+// UNQUAL-DAG: "foo"
+// QUAL-DAG: "foo::foo"
+
+ static foo* static_method() { return 0; }
+// UNQUAL-DAG: "static_method"
+// QUAL-DAG: "foo::static_method"
+
+};
+
+void use_foo() {
+ foo f1, f2(1), f3((char*)0);
+ foo::static_method();
+}
+
+// UNQUAL-DAG: "operator+"
+// QUAL-DAG: "foo::operator+"
+int foo::operator+(int a) { return a; }
+
+// PR17371
+struct OverloadedNewDelete {
+ // __cdecl
+ void *operator new(__SIZE_TYPE__);
+ void *operator new[](__SIZE_TYPE__);
+ void operator delete(void *);
+ void operator delete[](void *);
+ // __thiscall
+ int operator+(int);
+};
+
+void *OverloadedNewDelete::operator new(__SIZE_TYPE__ s) { return 0; }
+void *OverloadedNewDelete::operator new[](__SIZE_TYPE__ s) { return 0; }
+void OverloadedNewDelete::operator delete(void *) { }
+void OverloadedNewDelete::operator delete[](void *) { }
+int OverloadedNewDelete::operator+(int x) { return x; };
+
+// UNQUAL-DAG: "operator new"
+// UNQUAL-DAG: "operator new[]"
+// UNQUAL-DAG: "operator delete"
+// UNQUAL-DAG: "operator delete[]"
+// UNQUAL-DAG: "operator+"
+// QUAL-DAG: "OverloadedNewDelete::operator new"
+// QUAL-DAG: "OverloadedNewDelete::operator new[]"
+// QUAL-DAG: "OverloadedNewDelete::operator delete"
+// QUAL-DAG: "OverloadedNewDelete::operator delete[]"
+// QUAL-DAG: "OverloadedNewDelete::operator+"
+
+
+template <typename T, void (*)(void)>
+void fn_tmpl() {}
+
+template void fn_tmpl<int, freefunc>();
+// CHECK-DAG: "fn_tmpl<int,&freefunc>"
+
+template <typename A, typename B, typename C> struct ClassTemplate { A a; B b; C c; };
+ClassTemplate<char, short, ClassTemplate<int, int, int> > f;
+// This will only show up in normal debug builds.
+// UNQUAL-DAG: "ClassTemplate<char,short,ClassTemplate<int,int,int> >"
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-codeview-injected-class.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-codeview-injected-class.cpp
new file mode 100644
index 0000000..b421b2b
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-codeview-injected-class.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 %s -std=c++11 -triple=i686-pc-windows-msvc -debug-info-kind=limited -gcodeview -emit-llvm -o - | FileCheck %s
+
+// The injected class names in this test were accidentally making it into our
+// nested class record debug info. Make sure they don't appear there.
+
+// PR28790
+
+struct A {
+ const char *m_fn1();
+ template <typename> class B;
+ template <typename> class C;
+ template <typename FunctionIdT> class C<B<FunctionIdT>>;
+};
+const char *A::m_fn1() { return nullptr; }
+
+// CHECK: ![[A:[^ ]*]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "A",
+// CHECK-SAME: elements: ![[elements:[0-9]+]]
+
+// CHECK: ![[elements]] = !{![[m_fn1:[0-9]+]]}
+
+// CHECK: ![[m_fn1]] = !DISubprogram(name: "m_fn1",
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-codeview-nested-types.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-codeview-nested-types.cpp
new file mode 100644
index 0000000..7c8f78e
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-codeview-nested-types.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-pc-windows-msvc -debug-info-kind=limited -gcodeview -emit-llvm -o - | FileCheck %s
+
+struct HasNested {
+ enum InnerEnum { _BUF_SIZE = 1 };
+ typedef int InnerTypedef;
+ enum { InnerEnumerator = 2 };
+ struct InnerStruct { };
+};
+HasNested f;
+
+// CHECK: ![[INNERENUM:[0-9]+]] = !DICompositeType(tag: DW_TAG_enumeration_type, name: "InnerEnum", {{.*}})
+// CHECK: ![[HASNESTED:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "HasNested",
+// CHECK-SAME: elements: ![[MEMBERS:[0-9]+]],
+//
+// CHECK: ![[MEMBERS]] = !{![[INNERENUM]], ![[INNERTYPEDEF:[0-9]+]], ![[UNNAMEDENUM:[0-9]+]], ![[INNERSTRUCT:[0-9]+]]}
+//
+// CHECK: ![[INNERTYPEDEF]] = !DIDerivedType(tag: DW_TAG_typedef, name: "InnerTypedef", scope: ![[HASNESTED]]{{.*}})
+//
+// CHECK: ![[UNNAMEDENUM]] = !DICompositeType(tag: DW_TAG_enumeration_type, scope: ![[HASNESTED]],
+// CHECK-SAME: elements: ![[UNNAMEDMEMBERS:[0-9]+]],
+// CHECK: ![[UNNAMEDMEMBERS]] = !{![[INNERENUMERATOR:[0-9]+]]}
+// CHECK: ![[INNERENUMERATOR]] = !DIEnumerator(name: "InnerEnumerator", value: 2)
+//
+// CHECK: ![[INNERSTRUCT]] = !DICompositeType(tag: DW_TAG_structure_type, name: "InnerStruct"
+// CHECK-SAME: flags: DIFlagFwdDecl
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-codeview-unnamed.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-codeview-unnamed.cpp
new file mode 100644
index 0000000..dd4cc9c
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-codeview-unnamed.cpp
@@ -0,0 +1,108 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -debug-info-kind=limited -S -emit-llvm -std=c++11 -o - %s | FileCheck --check-prefix LINUX %s
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -debug-info-kind=limited -gcodeview -S -emit-llvm -std=c++11 -o - %s | FileCheck --check-prefix MSVC %s
+
+int main(int argc, char* argv[], char* arge[]) {
+ //
+ // In CodeView, the LF_MFUNCTION entry for "bar()" refers to the forward
+ // reference of the unnamed struct. Visual Studio requires a unique
+ // identifier to match the LF_STRUCTURE forward reference to the definition.
+ //
+ struct { void bar() {} } one;
+ //
+ // LINUX: !{{[0-9]+}} = !DILocalVariable(name: "one"
+ // LINUX-SAME: type: [[TYPE_OF_ONE:![0-9]+]]
+ // LINUX-SAME: )
+ // LINUX: [[TYPE_OF_ONE]] = distinct !DICompositeType(
+ // LINUX-SAME: tag: DW_TAG_structure_type
+ // LINUX-NOT: name:
+ // LINUX-NOT: identifier:
+ // LINUX-SAME: )
+ //
+ // MSVC: !{{[0-9]+}} = !DILocalVariable(name: "one"
+ // MSVC-SAME: type: [[TYPE_OF_ONE:![0-9]+]]
+ // MSVC-SAME: )
+ // MSVC: [[TYPE_OF_ONE]] = distinct !DICompositeType
+ // MSVC-SAME: tag: DW_TAG_structure_type
+ // MSVC-SAME: name: "<unnamed-type-one>"
+ // MSVC-SAME: identifier: ".?AU<unnamed-type-one>@?1??main@@9@"
+ // MSVC-SAME: )
+
+
+ // In CodeView, the LF_POINTER entry for "ptr2unnamed" refers to the forward
+ // reference of the unnamed struct. Visual Studio requires a unique
+ // identifier to match the LF_STRUCTURE forward reference to the definition.
+ //
+ struct { int bar; } two = { 42 };
+ int decltype(two)::*ptr2unnamed = &decltype(two)::bar;
+ //
+ // LINUX: !{{[0-9]+}} = !DILocalVariable(name: "two"
+ // LINUX-SAME: type: [[TYPE_OF_TWO:![0-9]+]]
+ // LINUX-SAME: )
+ // LINUX: [[TYPE_OF_TWO]] = distinct !DICompositeType(
+ // LINUX-SAME: tag: DW_TAG_structure_type
+ // LINUX-NOT: name:
+ // LINUX-NOT: identifier:
+ // LINUX-SAME: )
+ //
+ // MSVC: !{{[0-9]+}} = !DILocalVariable(name: "two"
+ // MSVC-SAME: type: [[TYPE_OF_TWO:![0-9]+]]
+ // MSVC-SAME: )
+ // MSVC: [[TYPE_OF_TWO]] = distinct !DICompositeType
+ // MSVC-SAME: tag: DW_TAG_structure_type
+ // MSVC-SAME: name: "<unnamed-type-two>"
+ // MSVC-SAME: identifier: ".?AU<unnamed-type-two>@?2??main@@9@"
+ // MSVC-SAME: )
+
+
+ // In DWARF, named structures which are not externally visibile do not
+ // require an identifier. In CodeView, named structures are given an
+ // identifier.
+ //
+ struct named { int bar; int named::* p2mem; } three = { 42, &named::bar };
+ //
+ // LINUX: !{{[0-9]+}} = !DILocalVariable(name: "three"
+ // LINUX-SAME: type: [[TYPE_OF_THREE:![0-9]+]]
+ // LINUX-SAME: )
+ // LINUX: [[TYPE_OF_THREE]] = distinct !DICompositeType(
+ // LINUX-SAME: tag: DW_TAG_structure_type
+ // LINUX-SAME: name: "named"
+ // LINUX-NOT: identifier:
+ // LINUX-SAME: )
+ //
+ // MSVC: !{{[0-9]+}} = !DILocalVariable(name: "three"
+ // MSVC-SAME: type: [[TYPE_OF_THREE:![0-9]+]]
+ // MSVC-SAME: )
+ // MSVC: [[TYPE_OF_THREE]] = distinct !DICompositeType
+ // MSVC-SAME: tag: DW_TAG_structure_type
+ // MSVC-SAME: name: "named"
+ // MSVC-SAME: identifier: ".?AUnamed@?1??main@@9@"
+ // MSVC-SAME: )
+
+
+ // In CodeView, the LF_MFUNCTION entry for the lambda "operator()" routine
+ // refers to the forward reference of the unnamed LF_CLASS for the lambda.
+ // Visual Studio requires a unique identifier to match the forward reference
+ // of the LF_CLASS to its definition.
+ //
+ auto four = [argc](int i) -> int { return argc == i ? 1 : 0; };
+ //
+ // LINUX: !{{[0-9]+}} = !DILocalVariable(name: "four"
+ // LINUX-SAME: type: [[TYPE_OF_FOUR:![0-9]+]]
+ // LINUX-SAME: )
+ // LINUX: [[TYPE_OF_FOUR]] = distinct !DICompositeType(
+ // LINUX-SAME: tag: DW_TAG_class_type
+ // LINUX-NOT: name:
+ // LINUX-NOT: identifier:
+ // LINUX-SAME: )
+ //
+ // MSVC: !{{[0-9]+}} = !DILocalVariable(name: "four"
+ // MSVC-SAME: type: [[TYPE_OF_FOUR:![0-9]+]]
+ // MSVC-SAME: )
+ // MSVC: [[TYPE_OF_FOUR]] = distinct !DICompositeType
+ // MSVC-SAME: tag: DW_TAG_class_type
+ // MSVC-NOT: name:
+ // MSVC-SAME: identifier: ".?AV<lambda_0>@?0??main@@9@"
+ // MSVC-SAME: )
+
+ return 0;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-codeview-var-templates.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-codeview-var-templates.cpp
new file mode 100644
index 0000000..0470c13
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-codeview-var-templates.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 %s -std=c++14 -triple=i686-pc-windows-msvc -debug-info-kind=limited -gcodeview -emit-llvm -o - | FileCheck %s
+
+// Don't emit static data member debug info for variable templates.
+// PR38004
+
+struct TestImplicit {
+ template <typename T>
+ static const __SIZE_TYPE__ size_var = sizeof(T);
+};
+int instantiate_test1() { return TestImplicit::size_var<int> + TestImplicit::size_var<TestImplicit>; }
+TestImplicit gv1;
+
+// CHECK: ![[empty:[0-9]+]] = !{}
+
+// CHECK: ![[A:[^ ]*]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "TestImplicit",
+// CHECK-SAME: elements: ![[empty]]
+
+template <typename T> bool vtpl;
+struct TestSpecialization {
+ template <typename T, typename U> static const auto sdm = vtpl<T>;
+ template <> static const auto sdm<int, int> = false;
+} gv2;
+
+// CHECK: ![[A:[^ ]*]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "TestSpecialization",
+// CHECK-SAME: elements: ![[empty]]
+
+template <class> bool a;
+template <typename> struct b;
+struct TestPartial {
+ template <typename... e> static auto d = a<e...>;
+ template <typename... e> static auto d<b<e...>> = d<e...>;
+} c;
+
+// CHECK: ![[A:[^ ]*]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "TestPartial",
+// CHECK-SAME: elements: ![[empty]]
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-composite-cc.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-composite-cc.cpp
new file mode 100644
index 0000000..d4d4046
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-composite-cc.cpp
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=standalone -triple %itanium_abi_triple %s -o - | FileCheck %s
+
+// Not trivially copyable because of the explicit destructor.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "RefDtor",{{.*}}flags: DIFlagTypePassByReference
+struct RefDtor {
+ int i;
+ ~RefDtor() {}
+} refDtor;
+
+// Not trivially copyable because of the explicit copy constructor.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "RefCopy",{{.*}}flags: DIFlagTypePassByReference
+struct RefCopy {
+ int i;
+ RefCopy() = default;
+ RefCopy(RefCopy &Copy) {}
+} refCopy;
+
+// POD-like type even though it defines a destructor.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "Podlike", {{.*}}flags: DIFlagTypePassByValue
+struct Podlike {
+ int i;
+ Podlike() = default;
+ Podlike(Podlike &&Move) = default;
+ ~Podlike() = default;
+} podlike;
+
+
+// This is a POD type.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "Pod",{{.*}}flags: DIFlagTypePassByValue
+struct Pod {
+ int i;
+} pod;
+
+// This is definitely not a POD type.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "Complex",{{.*}}flags: DIFlagTypePassByReference
+struct Complex {
+ Complex() {}
+ Complex(Complex &Copy) : i(Copy.i) {};
+ int i;
+} complex;
+
+// This type is manually marked as trivial_abi.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "Marked",{{.*}}flags: DIFlagTypePassByValue
+struct __attribute__((trivial_abi)) Marked {
+ int *p;
+ Marked();
+ ~Marked();
+ Marked(const Marked &) noexcept;
+ Marked &operator=(const Marked &);
+} marked;
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-context.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-context.cpp
new file mode 100644
index 0000000..1f7fa04
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-context.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -triple x86_64-apple-darwin %s -o - | FileCheck %s
+// PR11345
+
+class locale {
+private:
+ void _M_add_reference() const throw() {
+ }
+};
+class ios_base {
+ locale _M_ios_locale;
+public:
+ class Init {
+ };
+};
+static ios_base::Init __ioinit;
+
+// CHECK-NOT: _M_ios_locale
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-ctor.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-ctor.cpp
new file mode 100644
index 0000000..c31eebe
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-ctor.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang -emit-llvm -g -S %s -o - | FileCheck %s
+
+struct X {
+ X(int v);
+
+ int value;
+};
+
+X::X(int v) {
+ // CHECK_TEMPORARILY_DISABLED: call void @_ZN1XC2Ei(%struct.X* %this1, i32 %tmp), !dbg
+ // TEMPORARY CHECK: X
+ value = v;
+}
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-ctor2.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-ctor2.cpp
new file mode 100644
index 0000000..95b0608
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-ctor2.cpp
@@ -0,0 +1,16 @@
+// FIXME: Check IR rather than asm, then triple is not needed.
+// RUN: %clang --target=%itanium_abi_triple -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/src/llvm-project/clang/test/CodeGenCXX/debug-info-cxx0x.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-cxx0x.cpp
new file mode 100644
index 0000000..4c31f60
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-cxx0x.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -emit-llvm-only -std=c++11 -debug-info-kind=limited %s
+
+namespace PR9414 {
+ int f() {
+ auto x = 0;
+ return x;
+ }
+}
+
+// Don't crash.
+namespace PR13570 {
+ template<typename T, typename U> struct P {};
+ template<typename T> struct A {
+ template<typename U> static P<T,U> isa(U);
+ decltype(isa(int())) f() {}
+ };
+ template struct A<int>;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-cxx1y.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-cxx1y.cpp
new file mode 100644
index 0000000..f1298b1
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-cxx1y.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm-only -std=c++14 -emit-llvm -debug-info-kind=limited %s -o - | FileCheck %s
+
+// CHECK: imports: [[IMPS:![0-9]*]]
+// CHECK: [[EMPTY:![0-9]*]] = !{}
+
+// CHECK: [[IMPS]] = !{[[IMP:![0-9]*]]}
+// CHECK: [[IMP]] = !DIImportedEntity(
+// CHECK-SAME: entity: [[F3:![0-9]*]]
+// CHECK: [[F3]] = distinct !DISubprogram(name: "f3"
+// CHECK-SAME: type: [[SUBROUTINE_TYPE:![0-9]*]]
+// CHECK: [[SUBROUTINE_TYPE]] = !DISubroutineType(types: [[TYPE_LIST:![0-9]*]])
+// CHECK: [[TYPE_LIST]] = !{[[INT:![0-9]*]]}
+// CHECK: [[INT]] = !DIBasicType(name: "int"
+
+// CHECK: [[FOO:![0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "foo",
+// CHECK-SAME: elements: [[EMPTY]]
+
+// FIXME: The context of this definition should be the CU/file scope, not the class.
+// CHECK: !DISubprogram(name: "func", {{.*}} scope: [[FOO]]
+// CHECK-SAME: type: [[SUBROUTINE_TYPE]]
+// CHECK-SAME: DISPFlagDefinition
+// CHECK-SAME: declaration: [[FUNC_DECL:![0-9]*]]
+// CHECK: [[FUNC_DECL]] = !DISubprogram(name: "func",
+// CHECK-SAME: scope: [[FOO]]
+// CHECK-SAME: type: [[SUBROUTINE_TYPE]]
+// CHECK-SAME: spFlags: 0
+
+struct foo {
+ static auto func();
+};
+
+foo f;
+
+auto foo::func() {
+ return 1;
+}
+
+namespace ns {
+auto f2();
+auto f3() {
+ return 0;
+}
+}
+using ns::f2;
+using ns::f3;
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-decl-nested.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-decl-nested.cpp
new file mode 100644
index 0000000..5345ff2
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-decl-nested.cpp
@@ -0,0 +1,77 @@
+// RUN: %clang_cc1 -std=c++11 -debug-info-kind=standalone -emit-llvm -triple x86_64-apple-darwin %s -o %t
+// RUN: cat %t | FileCheck %s -check-prefix=CHECK0
+// RUN: cat %t | FileCheck %s -check-prefix=CHECK1
+// RUN: cat %t | FileCheck %s -check-prefix=CHECK2
+//
+// This test ensures that we associate a declaration with the
+// definition of the constructor for OuterClass. The declaration is
+// necessary so the backend can emit the DW_AT_specification attribute
+// for the definition.
+//
+// rdar://problem/13116508
+
+class Foo;
+class OuterClass
+{
+ static class InnerClass {
+ public:
+ InnerClass(); // Here createContextChain() generates a limited type for OuterClass.
+ } theInnerClass;
+// CHECK0: ![[DECL:[0-9]+]] = !DISubprogram(name: "OuterClass"
+// CHECK0-SAME: line: [[@LINE+2]]
+// CHECK0-SAME: spFlags: 0
+ OuterClass(const Foo *); // line 10
+};
+OuterClass::InnerClass OuterClass::theInnerClass; // This toplevel decl causes InnerClass to be generated.
+// CHECK0: !DISubprogram(name: "OuterClass"
+// CHECK0-SAME: line: [[@LINE+3]]
+// CHECK0-SAME: DISPFlagDefinition
+// CHECK0-SAME: declaration: ![[DECL]]
+OuterClass::OuterClass(const Foo *meta) { } // line 13
+
+
+
+
+
+
+class Foo1;
+class OuterClass1
+{
+ static class InnerClass1 {
+ public:
+ InnerClass1();
+ } theInnerClass1;
+// CHECK1: ![[DECL:[0-9]+]] = !DISubprogram(name: "Bar"
+// CHECK1-SAME: line: [[@LINE+2]]
+// CHECK1-SAME: spFlags: 0
+ void Bar(const Foo1 *);
+};
+OuterClass1::InnerClass1 OuterClass1::theInnerClass1;
+// CHECK1: !DISubprogram(name: "Bar"
+// CHECK1-SAME: line: [[@LINE+3]]
+// CHECK1-SAME: DISPFlagDefinition
+// CHECK1-SAME: declaration: ![[DECL]]
+void OuterClass1::Bar(const Foo1 *meta) { }
+
+
+
+
+
+class Foo2;
+class OuterClass2
+{
+ static class InnerClass2 {
+ public:
+ InnerClass2();
+ } theInnerClass2;
+// CHECK2: ![[DECL:[0-9]+]] = !DISubprogram(name: "~OuterClass2"
+// CHECK2-SAME: line: [[@LINE+2]]
+// CHECK2-SAME: spFlags: 0
+ ~OuterClass2(); // line 10
+};
+OuterClass2::InnerClass2 OuterClass2::theInnerClass2;
+// CHECK4: !DISubprogram(name: "~OuterClass2"
+// CHECK4-SAME: line: [[@LINE+3]]
+// CHECK4-SAME: DISPFlagDefinition
+// CHECK4-SAME: declaration: ![[DECL]]
+OuterClass2::~OuterClass2() { }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-determinism.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-determinism.cpp
new file mode 100644
index 0000000..ea88b80
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-determinism.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -S -emit-llvm -debug-info-kind=limited -o %t1.ll %s
+// RUN: %clang_cc1 -S -emit-llvm -debug-info-kind=limited -o %t2.ll %s
+// RUN: diff %t1.ll %t2.ll
+
+template <int N> struct C {
+ template <int M> int f() {
+ int arr[M] = {};
+ return arr[M/2] + C<M/2>().template f<M-1>();
+ }
+};
+template <> template <> int C<0>::f<0>() { return 0; }
+template <> template <> int C<0>::f<1>() { return 0; }
+template <> template <> int C<1>::f<0>() { return 0; }
+template <> template <> int C<1>::f<1>() { return 0; }
+
+int x = C<0>().f<64>();
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-dllimport-base-class.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-dllimport-base-class.cpp
new file mode 100644
index 0000000..855ecaa
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-dllimport-base-class.cpp
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -triple i386-pc-windows -emit-llvm -gcodeview -debug-info-kind=limited -fms-compatibility %s -x c++ -o - | FileCheck %s
+
+// Ensure we emit debug info for the full definition of base classes that will
+// be imported from a DLL. Otherwise, the debugger wouldn't be able to show the
+// members.
+
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "ImportedAfterCompletion",
+// CHECK-NOT: DIFlagFwdDecl
+// CHECK-SAME: ){{$}}
+
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "OutOfLineCtor",
+// CHECK-SAME: DIFlagFwdDecl
+// CHECK-SAME: ){{$}}
+
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "ImportedBase",
+// CHECK-NOT: DIFlagFwdDecl
+// CHECK-SAME: ){{$}}
+
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "ImportedMethod",
+// CHECK-NOT: DIFlagFwdDecl
+// CHECK-SAME: ){{$}}
+
+
+struct ImportedAfterCompletion;
+ImportedAfterCompletion *force_fwd_decl;
+struct __declspec(dllimport) ImportedAfterCompletion {
+ virtual ~ImportedAfterCompletion();
+};
+
+struct OutOfLineCtor {
+ OutOfLineCtor();
+ virtual void Foo();
+};
+
+struct __declspec(dllimport) ImportedBase {
+ ImportedBase();
+ virtual void Foo();
+};
+
+struct DerivedFromImported : public ImportedBase {};
+
+struct ImportedMethod {
+ ImportedMethod();
+ virtual void Foo();
+ static void __declspec(dllimport) create();
+};
+
+int main() {
+ ImportedAfterCompletion c;
+ OutOfLineCtor o;
+ DerivedFromImported d;
+ ImportedMethod m;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp
new file mode 100644
index 0000000..3b23ebf
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=standalone -triple x86_64-apple-darwin %s -o - | FileCheck %s
+
+class Test
+{
+public:
+ Test () : reserved (new data()) {}
+
+ unsigned
+ getID() const
+ {
+ return reserved->objectID;
+ }
+protected:
+ struct data {
+ unsigned objectID;
+ };
+ data* reserved;
+};
+
+Test t;
+
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "data"
+// CHECK: !DIDerivedType(tag: DW_TAG_pointer_type
+// CHECK-NOT: !DICompositeType(tag: DW_TAG_structure_type, name: "data"
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-enum-class.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-enum-class.cpp
new file mode 100644
index 0000000..3664c67
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-enum-class.cpp
@@ -0,0 +1,124 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -triple x86_64-apple-darwin -std=c++11 %s -o - | FileCheck %s
+
+enum class A { A1=1 }; // underlying type is int by default
+enum class B: unsigned long { B1=1 }; // underlying type is unsigned long
+enum C { C1 = 1 };
+enum D : short; // enum forward declaration
+enum Z : int;
+A a;
+B b;
+C c;
+D d;
+
+// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "A"
+// CHECK-SAME: line: 3
+// CHECK-SAME: baseType: ![[INT:[0-9]+]]
+// CHECK-SAME: size: 32
+// CHECK-NOT: offset:
+// CHECK-SAME: flags: DIFlagEnumClass
+// CHECK-SAME: ){{$}}
+// CHECK: ![[INT]] = !DIBasicType(name: "int"
+// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "B"
+// CHECK-SAME: line: 4
+// CHECK-SAME: baseType: ![[ULONG:[0-9]+]]
+// CHECK-SAME: size: 64
+// CHECK-NOT: offset:
+// CHECK-SAME: flags: DIFlagEnumClass
+// CHECK-SAME: ){{$}}
+// CHECK: ![[ULONG]] = !DIBasicType(name: "long unsigned int"
+// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "C"
+// CHECK-SAME: line: 5
+// CHECK-SAME: baseType: ![[ULONG:[0-9]+]]
+// CHECK-SAME: size: 32
+// CHECK-NOT: offset:
+// CHECK-NOT: flags:
+// CHECK-SAME: ){{$}}
+
+namespace PR14029 {
+ // Make sure this doesn't crash/assert.
+ template <typename T> struct Test {
+ enum class Tag {
+ test = 0
+ };
+ Test() {
+ auto t = Tag::test;
+ }
+ Tag tag() const { return static_cast<Tag>(1); }
+ };
+ Test<int> t;
+}
+
+namespace test2 {
+// FIXME: this should just be a declaration under -fno-standalone-debug
+// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "E"
+// CHECK-SAME: scope: [[TEST2:![0-9]+]]
+// CHECK-NOT: DIFlagEnumClass
+// CHECK-SAME: elements: [[TEST_ENUMS:![0-9]+]]
+// CHECK-SAME: identifier: "_ZTSN5test21EE"
+// CHECK: [[TEST2]] = !DINamespace(name: "test2"
+// CHECK: [[TEST_ENUMS]] = !{[[TEST_E:![0-9]*]]}
+// CHECK: [[TEST_E]] = !DIEnumerator(name: "e", value: 0)
+enum E : int;
+void func(E *) {
+}
+enum E : int { e };
+}
+
+namespace test3 {
+// FIXME: this should just be a declaration under -fno-standalone-debug
+// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "E"
+// CHECK-SAME: scope: [[TEST3:![0-9]+]]
+// CHECK-NOT: DIFlagEnumClass
+// CHECK-SAME: elements: [[TEST_ENUMS]]
+// CHECK-SAME: identifier: "_ZTSN5test31EE"
+// CHECK: [[TEST3]] = !DINamespace(name: "test3"
+enum E : int { e };
+void func(E *) {
+}
+}
+
+namespace test4 {
+// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "E"
+// CHECK-SAME: scope: [[TEST4:![0-9]+]]
+// CHECK-NOT: DIFlagEnumClass
+// CHECK-SAME: elements: [[TEST_ENUMS]]
+// CHECK-SAME: identifier: "_ZTSN5test41EE"
+// CHECK: [[TEST4]] = !DINamespace(name: "test4"
+enum E : int;
+void f1(E *) {
+}
+enum E : int { e };
+void f2(E) {
+}
+}
+
+// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "D"
+// CHECK-SAME: line: 6
+// CHECK-SAME: size: 16
+// CHECK-NOT: offset:
+// CHECK-SAME: flags: DIFlagFwdDecl
+
+// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "Z"
+// CHECK-NOT: scope:
+// CHECK-SAME: flags: DIFlagFwdDecl
+void fz() { Z z; }
+
+namespace test5 {
+// CHECK: [[TEST5:![0-9]+]] = !DINamespace(name: "test5"
+// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "E"
+// CHECK-SAME: scope: [[TEST5]]
+// CHECK-SAME: flags: DIFlagFwdDecl
+// CHECK-SAME: identifier: "_ZTSN5test51EE"
+enum E : int;
+void f1(E *) {
+}
+}
+
+namespace test6 {
+// Ensure typedef'd enums aren't manifest by debug info generation.
+// This could cause "typedef changes linkage of anonymous type, but linkage was
+// already computed" errors.
+// CHECK-NOT: test6
+typedef enum {
+} E;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-enum.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-enum.cpp
new file mode 100644
index 0000000..447edba
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-enum.cpp
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -debug-info-kind=limited %s -o - | FileCheck %s
+
+// CHECK: !DICompileUnit(
+// CHECK-SAME: enums: [[ENUMS:![0-9]*]]
+// CHECK: [[ENUMS]] = !{[[E1:![0-9]*]], [[E2:![0-9]*]], [[E3:![0-9]*]]}
+
+namespace test1 {
+// CHECK: [[E1]] = !DICompositeType(tag: DW_TAG_enumeration_type, name: "e"
+// CHECK-SAME: scope: [[TEST1:![0-9]*]]
+// CHECK-SAME: elements: [[TEST1_ENUMS:![0-9]*]]
+// CHECK-SAME: identifier: "_ZTSN5test11eE"
+// CHECK: [[TEST1]] = !DINamespace(name: "test1"
+// CHECK: [[TEST1_ENUMS]] = !{[[TEST1_E:![0-9]*]]}
+// CHECK: [[TEST1_E]] = !DIEnumerator(name: "E", value: 0, isUnsigned: true)
+enum e { E };
+void foo() {
+ int v = E;
+}
+}
+
+namespace test2 {
+// rdar://8195980
+// CHECK: [[E2]] = !DICompositeType(tag: DW_TAG_enumeration_type, name: "e"
+// CHECK-SAME: scope: [[TEST2:![0-9]+]]
+// CHECK-SAME: elements: [[TEST1_ENUMS]]
+// CHECK-SAME: identifier: "_ZTSN5test21eE"
+// CHECK: [[TEST2]] = !DINamespace(name: "test2"
+enum e { E };
+bool func(int i) {
+ return i == E;
+}
+}
+
+namespace test3 {
+// CHECK: [[E3]] = !DICompositeType(tag: DW_TAG_enumeration_type, name: "e"
+// CHECK-SAME: scope: [[TEST3:![0-9]*]]
+// CHECK-SAME: elements: [[TEST3_ENUMS:![0-9]*]]
+// CHECK-SAME: identifier: "_ZTSN5test31eE"
+// CHECK: [[TEST3]] = !DINamespace(name: "test3"
+// CHECK: [[TEST3_ENUMS]] = !{[[TEST3_E:![0-9]*]]}
+// CHECK: [[TEST3_E]] = !DIEnumerator(name: "E", value: -1)
+enum e { E = -1 };
+void func() {
+ e x;
+}
+}
+
+namespace test4 {
+// Don't try to build debug info for a dependent enum.
+// CHECK-NOT: test4
+template <typename T>
+struct S {
+ enum e { E = T::v };
+};
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-explicit-cast.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-explicit-cast.cpp
new file mode 100644
index 0000000..028a776
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-explicit-cast.cpp
@@ -0,0 +1,46 @@
+// RUN: %clangxx -c -target %itanium_abi_triple -g %s -emit-llvm -S -o - | FileCheck %s
+// RUN: %clangxx -c -target %ms_abi_triple -g %s -emit-llvm -S -o - | FileCheck %s
+
+struct Foo {
+ int A;
+ Foo() : A(1){};
+};
+
+struct Bar {
+ int B;
+ Bar() : B(2){};
+};
+
+struct Baz {
+ int C;
+ Baz() : C(3){};
+};
+
+struct Qux {
+ int d() { return 4; }
+ Qux() {};
+};
+
+struct Quux {
+ int E;
+ Quux() : E(5){};
+};
+
+typedef int(Qux::*TD)();
+typedef int(Qux::*TD1)();
+int Val = reinterpret_cast<Baz *>(0)->C;
+int main() {
+ Bar *PB = new Bar;
+ TD d = &Qux::d;
+ (void)reinterpret_cast<TD1>(d);
+
+ return reinterpret_cast<Foo *>(PB)->A + reinterpret_cast<Quux *>(0)->E;
+}
+
+// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "Foo",
+// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "Bar",
+// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "Baz",
+// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "Qux",
+// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "Quux",
+// CHECK-DAG: !DIDerivedType(tag: DW_TAG_typedef, name: "TD",
+// CHECK-DAG: !DIDerivedType(tag: DW_TAG_typedef, name: "TD1",
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-fn-template.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-fn-template.cpp
new file mode 100644
index 0000000..2aed4be
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-fn-template.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang -emit-llvm -g -S %s -o - | FileCheck %s
+
+template<typename T>
+struct XF {
+ T member;
+};
+
+template<typename T>
+T fx(XF<T> xi) {
+ return xi.member;
+}
+
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "XF<int>"
+// CHECK: !DITemplateTypeParameter(name: "T"
+template int fx(XF<int>);
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-friend.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-friend.cpp
new file mode 100644
index 0000000..b103b14
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-friend.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang -emit-llvm -S -g %s -o - | FileCheck %s
+
+class MyFriend;
+
+class SomeClass {
+ friend class MyFriend;
+ typedef int SomeType;
+};
+
+SomeClass *x;
+
+struct MyFriend {
+ static void func(SomeClass::SomeType) {
+ }
+};
+
+// Emitting debug info for friends unnecessarily bloats debug info without any
+// known benefit or debugger feature that requires it. Re-enable this is a
+// use-case appears.
+// CHECK-NOT: DW_TAG_friend
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-function-context.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-function-context.cpp
new file mode 100644
index 0000000..40a6643
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-function-context.cpp
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -triple x86_64-pc-linux-gnu %s -o - | FileCheck %s
+
+struct C {
+ void member_function();
+ static int static_member_function();
+ static int static_member_variable;
+};
+
+int C::static_member_variable = 0;
+
+void C::member_function() { static_member_variable = 0; }
+
+int C::static_member_function() { return static_member_variable; }
+
+C global_variable;
+
+int global_function() { return -1; }
+
+namespace ns {
+void global_namespace_function() { global_variable.member_function(); }
+int global_namespace_variable = 1;
+}
+
+// Check that the functions that belong to C have C as a context and the
+// functions that belong to the namespace have it as a context, and the global
+// function has the file as a context.
+
+// CHECK: ![[FILE:[0-9]+]] = !DIFile(filename: "{{.*}}context.cpp",
+// CHECK: ![[C:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "C",
+// CHECK: ![[NS:.*]] = !DINamespace(name: "ns"
+// CHECK: !DISubprogram(name: "member_function",{{.*}} scope: ![[C]],{{.*}} DISPFlagDefinition
+
+// CHECK: !DISubprogram(name: "static_member_function",{{.*}} scope: ![[C]],{{.*}} DISPFlagDefinition
+
+// CHECK: !DISubprogram(name: "global_function",{{.*}} scope: ![[FILE]],{{.*}} DISPFlagDefinition
+
+// CHECK: !DISubprogram(name: "global_namespace_function",{{.*}} scope: ![[NS]],{{.*}} DISPFlagDefinition
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-fwd-ref.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-fwd-ref.cpp
new file mode 100644
index 0000000..219e796
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-fwd-ref.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -triple x86_64-apple-darwin %s -o - | FileCheck %s
+
+struct baz {
+ int h;
+ baz(int a) : h(a) {}
+};
+
+struct bar {
+ baz b;
+ baz& b_ref;
+ bar(int x) : b(x), b_ref(b) {}
+};
+
+int main(int argc, char** argv) {
+ bar myBar(1);
+ return 0;
+}
+
+// Make sure we have two DW_TAG_structure_types for baz and bar and no forward
+// references.
+// CHECK-NOT: DIFlagFwdDecl
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "bar"
+// CHECK-NOT: DIFlagFwdDecl
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "baz"
+// CHECK-NOT: DIFlagFwdDecl
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-fwd-template-param.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-fwd-template-param.cpp
new file mode 100644
index 0000000..2983f84
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-fwd-template-param.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 %s -triple=%itanium_abi_triple -debug-info-kind=limited -debug-forward-template-params -emit-llvm -o - | FileCheck --check-prefix=CHILD %s
+// RUN: %clang_cc1 %s -triple=%itanium_abi_triple -debug-info-kind=limited -emit-llvm -o - | FileCheck --check-prefix=NONE %s
+// A DWARF forward declaration of a template instantiation should have template
+// parameter children (if we ask for them).
+
+template<typename T> class A;
+A<int> *p;
+
+// CHILD: !DICompositeType(tag: DW_TAG_class_type, name: "A<int>"
+// CHILD-SAME: flags: DIFlagFwdDecl
+// CHILD-SAME: templateParams: [[PARAM_LIST:![0-9]*]]
+// CHILD: [[PARAM_LIST]] = !{[[PARAM:![0-9]*]]}
+// CHILD: [[PARAM]] = !DITemplateTypeParameter(name: "T",
+// CHILD-SAME: type: [[BTYPE:![0-9]*]]
+// CHILD: [[BTYPE]] = !DIBasicType(name: "int"
+
+// NONE: !DICompositeType(tag: DW_TAG_class_type, name: "A<int>"
+// NONE-SAME: flags: DIFlagFwdDecl
+// NONE-NOT: templateParams:
+// NONE-SAME: )
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-gline-tables-only.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-gline-tables-only.cpp
new file mode 100644
index 0000000..ceb7856
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-gline-tables-only.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 %s -fno-rtti -debug-info-kind=line-tables-only -S -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -fno-rtti -debug-info-kind=line-directives-only -S -emit-llvm -o - | FileCheck %s
+// Checks that clang with "-gline-tables-only" or "-gline-directives-only" doesn't emit debug info
+// for variables and types.
+
+// CHECK-NOT: DW_TAG_namespace
+namespace NS {
+// CHECK-NOT: DW_TAG_class_type
+// CHECK-NOT: DW_TAG_friend
+class C { friend class D; };
+class D {};
+// CHECK-NOT: DW_TAG_inheritance
+class E : public C {
+ // CHECK-NOT: DW_TAG_reference type
+ void x(const D& d);
+};
+struct F {
+ enum X { };
+ void func(X);
+ virtual ~F();
+};
+F::~F() {
+}
+}
+
+// CHECK-NOT: DW_TAG_variable
+NS::C c;
+NS::D d;
+NS::E e;
+NS::F f;
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-global-ctor-dtor.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-global-ctor-dtor.cpp
new file mode 100644
index 0000000..0ede3c6
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-global-ctor-dtor.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 %s -debug-info-kind=limited -triple %itanium_abi_triple -fno-use-cxa-atexit -S -disable-O0-optnone -emit-llvm -o - \
+// RUN: | FileCheck %s --check-prefix=CHECK-NOKEXT
+// RUN: %clang_cc1 %s -debug-info-kind=limited -triple %itanium_abi_triple -fno-use-cxa-atexit -fapple-kext -S -disable-O0-optnone -emit-llvm -o - \
+// RUN: | FileCheck %s --check-prefix=CHECK-KEXT
+
+class A {
+ public:
+ A() {}
+ virtual ~A() {}
+};
+
+A glob;
+A array[2];
+
+void foo() {
+ static A stat;
+}
+
+// CHECK-NOKEXT: !DISubprogram(name: "__cxx_global_var_init",{{.*}} line: 12,{{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
+// CHECK-NOKEXT: !DISubprogram(name: "__dtor_glob",{{.*}} line: 12,{{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
+// CHECK-NOKEXT: !DISubprogram(name: "__cxx_global_var_init.1",{{.*}} line: 13,{{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
+// CHECK-NOKEXT: !DISubprogram(name: "__cxx_global_array_dtor",{{.*}} line: 13,{{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
+// CHECK-NOKEXT: !DISubprogram(name: "__dtor_array",{{.*}} line: 13,{{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
+// CHECK-NOKEXT: !DISubprogram(name: "__dtor__ZZ3foovE4stat",{{.*}} line: 16,{{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
+// CHECK-NOKEXT: !DISubprogram({{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
+
+// CHECK-KEXT: !DISubprogram({{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-global.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-global.cpp
new file mode 100644
index 0000000..5abc050
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-global.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -triple x86_64-none-linux-gnu -emit-llvm -debug-info-kind=limited %s -o - | FileCheck %s
+
+// Multiple references to the same constant should result in only one entry in
+// the globals list.
+
+namespace ns {
+const int cnst = 42;
+}
+int f1() {
+ return ns::cnst + ns::cnst;
+}
+
+// CHECK: !DICompileUnit(
+// CHECK-SAME: globals: [[GLOBALS:![0-9]*]]
+
+// CHECK: [[GLOBALS]] = !{[[CNST:![0-9]*]]}
+
+// CHECK: [[CNST]] = !DIGlobalVariableExpression(var: [[CNSTV:.*]], expr:
+// CHECK: [[CNSTV]] = distinct !DIGlobalVariable(name: "cnst",
+// CHECK-SAME: scope: [[NS:![0-9]*]]
+// CHECK: [[NS]] = !DINamespace(name: "ns"
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-globalinit.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-globalinit.cpp
new file mode 100644
index 0000000..09c7d59
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-globalinit.cpp
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -emit-llvm -o - %s -std=c++11 -debug-info-kind=limited | FileCheck %s
+
+void crash() {
+ volatile char *ptr = 0;
+ char x = *ptr;
+}
+
+int test() {
+ crash();
+ return 1;
+}
+
+static int i = test();
+__attribute__((nodebug)) static int j = test();
+static int k = test();
+
+int main(void) {}
+
+// CHECK-LABEL: define internal void @__cxx_global_var_init()
+// CHECK-NOT: __cxx_global_var_init
+// CHECK: %[[C0:.+]] = call i32 @_Z4testv(), !dbg ![[LINE:.*]]
+// CHECK-NOT: __cxx_global_var_init
+// CHECK: store i32 %[[C0]], i32* @_ZL1i, align 4, !dbg
+//
+// CHECK-LABEL: define internal void @__cxx_global_var_init.1()
+// CHECK-NOT: dbg
+// CHECK: %[[C1:.+]] = call i32 @_Z4testv()
+// CHECK-NOT: dbg
+// CHECK: store i32 %[[C1]], i32* @_ZL1j, align 4
+//
+// CHECK-LABEL: define internal void @__cxx_global_var_init.2()
+// CHECK-NOT: __cxx_global_var_init
+// CHECK: %[[C2:.+]] = call i32 @_Z4testv(), !dbg ![[LINE2:.*]]
+// CHECK-NOT: __cxx_global_var_init
+// CHECK: store i32 %[[C2]], i32* @_ZL1k, align 4, !dbg
+//
+// CHECK: ![[LINE]] = !DILocation(line: 13,
+// CHECK: ![[LINE2]] = !DILocation(line: 15,
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-indirect-field-decl.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-indirect-field-decl.cpp
new file mode 100644
index 0000000..126e1f6b
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-indirect-field-decl.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -triple x86_64-apple-darwin %s -o - | FileCheck %s
+//
+// Test that indirect field decls are handled gracefully.
+// rdar://problem/16348575
+//
+template <class T, int T::*ptr> class Foo { };
+
+struct Bar {
+ int i1;
+ // CHECK: ![[INT:[0-9]+]] = !DIBasicType(name: "int"
+ // CHECK: !DIDerivedType(tag: DW_TAG_member, scope:
+ // CHECK-SAME: line: [[@LINE+4]]
+ // CHECK-SAME: baseType: ![[UNION:[0-9]+]]
+ // CHECK-SAME: size: 32, offset: 32
+ // CHECK: ![[UNION]] = distinct !DICompositeType(tag: DW_TAG_union_type,{{.*}} identifier: "_ZTSN3BarUt_E")
+ union {
+ // CHECK: !DIDerivedType(tag: DW_TAG_member, name: "i2",
+ // CHECK-SAME: line: [[@LINE+5]]
+ // CHECK-SAME: baseType: ![[INT]]
+ // CHECK-SAME: size: 32
+ // CHECK-NOT: offset:
+ // CHECK-SAME: ){{$}}
+ int i2;
+ };
+};
+
+Foo<Bar, &Bar::i2> the_foo;
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-inheriting-constructor.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-inheriting-constructor.cpp
new file mode 100644
index 0000000..8e47a0d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-inheriting-constructor.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -debug-info-kind=standalone -std=c++11 -triple x86_64-darwin -emit-llvm -o - %s | FileCheck %s
+
+struct A {
+ A(int, ...);
+};
+struct B : A {
+ using A::A;
+};
+
+A::A(int i, ...) {}
+// CHECK: define void @{{.*}}foo
+// CHECK-NOT ret void
+// CHECK: call void @llvm.dbg.declare
+// CHECK-NOT ret void
+// CHECK: call void @llvm.dbg.declare(metadata %{{.*}}** %{{[^,]+}},
+// CHECK-SAME: metadata ![[THIS:[0-9]+]], metadata !DIExpression()), !dbg ![[LOC:[0-9]+]]
+// CHECK: ret void, !dbg ![[NOINL:[0-9]+]]
+// CHECK: ![[FOO:.*]] = distinct !DISubprogram(name: "foo"
+// CHECK-DAG: ![[A:.*]] = distinct !DISubprogram(name: "A", linkageName: "_ZN1BCI11AEiz"
+void foo() {
+// CHECK-DAG: ![[LOC]] = !DILocation(line: 0, scope: ![[A]], inlinedAt: ![[INL:[0-9]+]])
+// CHECK-DAG: ![[INL]] = !DILocation(line: [[@LINE+1]], scope: ![[FOO]])
+ B b(0);
+// CHECK: ![[NOINL]] = !DILocation(line: [[@LINE+1]], scope: !{{[0-9]+}})
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-inlined.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-inlined.cpp
new file mode 100644
index 0000000..d36715b
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-inlined.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -emit-llvm -triple i686-pc-windows-msvc19.0.24213 -gcodeview -debug-info-kind=limited -std=c++14 %s -o - | FileCheck %s
+// PR33997.
+struct WithDtor {
+ ~WithDtor();
+};
+struct Base {
+ Base(WithDtor);
+};
+class Forward : Base {
+ using Base::Base;
+};
+class A : Forward {
+ A();
+};
+class B : Forward {
+ B();
+};
+A::A() : Forward(WithDtor()) {}
+
+B::B() : Forward(WithDtor()) {}
+
+// CHECK: define{{.*}}A
+// CHECK-NOT: {{ ret }}
+// CHECK: store %class.Forward* %
+// CHECK-SAME: %class.Forward** %
+// CHECK-SAME: !dbg ![[INL:[0-9]+]]
+
+// CHECK: ![[INL]] = !DILocation(line: 10, scope: ![[SP:[0-9]+]], inlinedAt:
+// CHECK: ![[SP]] = distinct !DISubprogram(name: "Base", {{.*}} DISPFlagDefinition
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-lambda.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-lambda.cpp
new file mode 100644
index 0000000..a10765d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-lambda.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm \
+// RUN: -debug-info-kind=line-tables-only -dwarf-column-info -std=c++11 %s -o - | FileCheck %s
+
+// CHECK-LABEL: define{{.*}}lambda_in_func
+void lambda_in_func(int &ref) {
+ // CHECK: [[ref_slot:%.*]] = getelementptr inbounds %class.anon, %class.anon* {{.*}}, i32 0, i32 0, !dbg [[lambda_decl_loc:![0-9]+]]
+ // CHECK-NEXT: %1 = load i32*, i32** %ref.addr, align {{.*}}, !dbg [[capture_init_loc:![0-9]+]]
+ // CHECK-NEXT: store i32* %1, i32** %0, align {{.*}}, !dbg [[lambda_decl_loc]]
+ // CHECK-NEXT: call {{.*}}void {{.*}}, !dbg [[lambda_call_loc:![0-9]+]]
+
+ auto helper = [ // CHECK: [[lambda_decl_loc]] = !DILocation(line: [[@LINE]], column: 17
+ &]() { // CHECK: [[capture_init_loc]] = !DILocation(line: [[@LINE]], column: 18
+ ++ref;
+ };
+ helper(); // CHECK: [[lambda_call_loc]] = !DILocation(line: [[@LINE]]
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-large-constant.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-large-constant.cpp
new file mode 100644
index 0000000..5a0d4d2
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-large-constant.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -debug-info-kind=limited -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/src/llvm-project/clang/test/CodeGenCXX/debug-info-limited.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-limited.cpp
new file mode 100644
index 0000000..4467d20
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-limited.cpp
@@ -0,0 +1,37 @@
+// RUN: %clang -flimit-debug-info -emit-llvm -g -S %s -o - | FileCheck %s
+// RUN: %clang -flimit-debug-info -emit-llvm -g -S %s -o - | FileCheck --check-prefix=CHECK-C %s
+
+// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "A"
+// CHECK-NOT: DIFlagFwdDecl
+// CHECK-SAME: ){{$}}
+class A {
+public:
+ int z;
+};
+
+A *foo (A* x) {
+ A *a = new A(*x);
+ return a;
+}
+
+// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "B"
+// CHECK-SAME: flags: DIFlagFwdDecl
+
+class B {
+public:
+ int y;
+};
+
+extern int bar(B *b);
+int baz(B *b) {
+ return bar(b);
+}
+
+
+// CHECK-C: !DICompositeType(tag: DW_TAG_structure_type, name: "C"
+// CHECK-C-SAME: flags: DIFlagFwdDecl
+
+struct C {
+};
+
+C (*x)(C);
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-line-if.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-line-if.cpp
new file mode 100644
index 0000000..7e6cdb2
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-line-if.cpp
@@ -0,0 +1,71 @@
+// RUN: %clang_cc1 -debug-info-kind=limited -std=c++11 -S -emit-llvm %s -o - | FileCheck -allow-deprecated-dag-overlap %s
+// PR19864
+extern int v[2];
+int a = 0, b = 0;
+int main() {
+#line 100
+ for (int x : v)
+ if (x)
+ ++b; // CHECK: add nsw{{.*}}, 1
+ else
+ ++a; // CHECK: add nsw{{.*}}, 1
+ // The continuation block if the if statement should not share the
+ // location of the ++a statement. The branch back to the start of the loop
+ // should be attributed to the loop header line.
+
+ // CHECK: br label
+ // CHECK: br label
+ // CHECK: br label {{.*}}, !dbg [[DBG1:![0-9]*]], !llvm.loop [[L1:![0-9]*]]
+
+#line 200
+ while (a)
+ if (b)
+ ++b; // CHECK: add nsw{{.*}}, 1
+ else
+ ++a; // CHECK: add nsw{{.*}}, 1
+
+ // CHECK: br label
+ // CHECK: br label {{.*}}, !dbg [[DBG2:![0-9]*]], !llvm.loop [[L2:![0-9]*]]
+
+#line 300
+ for (; a; )
+ if (b)
+ ++b; // CHECK: add nsw{{.*}}, 1
+ else
+ ++a; // CHECK: add nsw{{.*}}, 1
+
+ // CHECK: br label
+ // CHECK: br label {{.*}}, !dbg [[DBG3:![0-9]*]], !llvm.loop [[L3:![0-9]*]]
+
+#line 400
+ int x[] = {1, 2};
+ for (int y : x)
+ if (b)
+ ++b; // CHECK: add nsw{{.*}}, 1
+ else
+ ++a; // CHECK: add nsw{{.*}}, 1
+
+ // CHECK: br label
+ // CHECK: br label {{.*}}, !dbg [[DBG4:![0-9]*]], !llvm.loop [[L4:![0-9]*]]
+
+ // CHECK-DAG: [[DBG1]] = !DILocation(line: 100, scope: !{{.*}})
+ // CHECK-DAG: [[DBG2]] = !DILocation(line: 200, scope: !{{.*}})
+ // CHECK-DAG: [[DBG3]] = !DILocation(line: 300, scope: !{{.*}})
+ // CHECK-DAG: [[DBG4]] = !DILocation(line: 401, scope: !{{.*}})
+
+ // CHECK-DAG: [[L1]] = distinct !{[[L1]], [[SLDBG1:![0-9]*]], [[ELDBG1:![0-9]*]]}
+ // CHECK-DAG: [[SLDBG1]] = !DILocation(line: 100, scope: !{{.*}})
+ // CHECK-DAG: [[ELDBG1]] = !DILocation(line: 104, scope: !{{.*}})
+
+ // CHECK-DAG: [[L2]] = distinct !{[[L2]], [[SLDBG2:![0-9]*]], [[ELDBG2:![0-9]*]]}
+ // CHECK-DAG: [[SLDBG2]] = !DILocation(line: 200, scope: !{{.*}})
+ // CHECK-DAG: [[ELDBG2]] = !DILocation(line: 204, scope: !{{.*}})
+
+ // CHECK-DAG: [[L3]] = distinct !{[[L3]], [[SLDBG3:![0-9]*]], [[ELDBG3:![0-9]*]]}
+ // CHECK-DAG: [[SLDBG3]] = !DILocation(line: 300, scope: !{{.*}})
+ // CHECK-DAG: [[ELDBG3]] = !DILocation(line: 304, scope: !{{.*}})
+
+ // CHECK-DAG: [[L4]] = distinct !{[[L4]], [[SLDBG4:![0-9]*]], [[ELDBG4:![0-9]*]]}
+ // CHECK-DAG: [[SLDBG4]] = !DILocation(line: 401, scope: !{{.*}})
+ // CHECK-DAG: [[ELDBG4]] = !DILocation(line: 405, scope: !{{.*}})
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-line.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-line.cpp
new file mode 100644
index 0000000..100cfa6
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-line.cpp
@@ -0,0 +1,324 @@
+// RUN: %clang_cc1 -w -debug-info-kind=line-tables-only -std=c++11 -fexceptions -fcxx-exceptions -S -mllvm -no-discriminators -emit-llvm %s -o - -triple %itanium_abi_triple | FileCheck %s
+// RUN: %clang_cc1 -w -debug-info-kind=line-tables-only -std=c++11 -fexceptions -fcxx-exceptions -S -mllvm -no-discriminators -emit-llvm %s -o - -triple i686-linux-gnu | FileCheck %s
+// RUN: %clang_cc1 -w -debug-info-kind=line-directives-only -std=c++11 -fexceptions -fcxx-exceptions -S -mllvm -no-discriminators -emit-llvm %s -o - -triple %itanium_abi_triple | FileCheck %s
+// RUN: %clang_cc1 -w -debug-info-kind=line-directives-only -std=c++11 -fexceptions -fcxx-exceptions -S -mllvm -no-discriminators -emit-llvm %s -o - -triple i686-linux-gnu | FileCheck %s
+
+int &src();
+int *sink();
+extern "C" __complex float complex_src();
+extern "C" __complex float *complex_sink();
+
+// CHECK-LABEL: define
+void f1() {
+ *sink()
+ // CHECK: store {{.*}}, !dbg [[DBG_F1:!.*]]
+#line 100
+ = //
+ src();
+}
+
+struct foo {
+ int i;
+ int &j;
+ __complex float k;
+ foo();
+};
+
+// CHECK-LABEL: define
+foo::foo()
+ :
+#line 200
+ i // CHECK: store i32 {{.*}} !dbg [[DBG_FOO_VALUE:!.*]]
+ (src()),
+ j // CHECK: store i32* {{.*}} !dbg [[DBG_FOO_REF:!.*]]
+ (src()),
+ k // CHECK: store float {{.*}} !dbg [[DBG_FOO_COMPLEX:!.*]]
+ (complex_src()) {
+}
+
+// CHECK-LABEL: define {{.*}}f2{{.*}}
+void f2() {
+ // CHECK: store float {{.*}} !dbg [[DBG_F2:!.*]]
+ *complex_sink()
+#line 300
+ = //
+ complex_src();
+}
+
+// CHECK-LABEL: define
+void f3() {
+ // CHECK: store float {{.*}} !dbg [[DBG_F3:!.*]]
+ *complex_sink()
+#line 400
+ += //
+ complex_src();
+}
+
+// CHECK-LABEL: define
+void f4() {
+#line 500
+ auto x // CHECK: store {{.*}} !dbg [[DBG_F4:!.*]]
+ = src();
+}
+
+// CHECK-LABEL: define
+void f5() {
+#line 600
+ auto x // CHECK: store float {{.*}} !dbg [[DBG_F5:!.*]]
+ = complex_src();
+}
+
+struct agg { int i; };
+agg agg_src();
+
+// CHECK-LABEL: define
+void f6() {
+ agg x;
+ // CHECK: call void @llvm.memcpy{{.*}} !dbg [[DBG_F6:!.*]]
+ x
+#line 700
+ = //
+ agg_src();
+}
+
+// CHECK-LABEL: define
+void f7() {
+ int *src1();
+ int src2();
+#line 800
+ int x = ( // CHECK: load {{.*}} !dbg [[DBG_F7:!.*]]
+ src1())[src2()];
+}
+
+// CHECK-LABEL: define
+void f8() {
+ int src1[1];
+ int src2();
+#line 900
+ int x = ( // CHECK: load {{.*}} !dbg [[DBG_F8:!.*]]
+ src1)[src2()];
+}
+
+// CHECK-LABEL: define
+void f9(int i) {
+ int src1[1][i];
+ int src2();
+#line 1000
+ auto x = ( // CHECK: getelementptr {{.*}} !dbg [[DBG_F9:!.*]]
+ src1)[src2()];
+}
+
+inline void *operator new(decltype(sizeof(1)), void *p) noexcept { return p; }
+
+// CHECK-LABEL: define
+void f10() {
+ void *void_src();
+ (
+ // CHECK: store {{.*}} !dbg [[DBG_F10_STORE:!.*]]
+#line 1100
+ new (void_src()) int(src()));
+}
+
+// noexcept just to simplify the codegen a bit
+void fn() noexcept(true);
+
+struct bar {
+ bar();
+ // noexcept(false) to convolute the global dtor
+ ~bar() noexcept(false);
+};
+// global ctor cleanup
+// CHECK-LABEL: define
+// CHECK: invoke{{ }}
+// CHECK: invoke{{ }}
+// CHECK: to label {{.*}}, !dbg [[DBG_GLBL_CTOR_B:!.*]]
+
+// terminate caller
+// CHECK-LABEL: define
+
+// global dtor cleanup
+// CHECK-LABEL: define
+// CHECK: invoke{{ }}
+// CHECK: invoke{{ }}
+// CHECK: to label {{.*}}, !dbg [[DBG_GLBL_DTOR_B:!.*]]
+#line 1200
+bar b[1] = { //
+ (fn(), //
+ bar())};
+
+// CHECK-LABEL: define
+__complex double f11() {
+ __complex double f;
+// CHECK: store {{.*}} !dbg [[DBG_F11:!.*]]
+#line 1300
+ return f;
+}
+
+// CHECK-LABEL: define
+void f12() {
+ int f12_1();
+ void f12_2(int = f12_1());
+// CHECK: call {{.*}}{{(signext )?}}i32 {{.*}} !dbg [[DBG_F12:!.*]]
+#line 1400
+ f12_2();
+}
+
+// CHECK-LABEL: define
+void f13() {
+// CHECK: call {{.*}} !dbg [[DBG_F13:!.*]]
+#define F13_IMPL 1, src()
+ 1,
+#line 1500
+ F13_IMPL;
+}
+
+struct f14_impl {
+ f14_impl(int);
+};
+
+// CHECK-LABEL: define
+struct f14_use {
+// CHECK: call {{.*}}f14_impl{{.*}}, !dbg [[DBG_F14_CTOR_CALL:![0-9]*]]
+#line 1600
+ f14_impl v{//
+ 1};
+ f14_use();
+};
+
+f14_use::f14_use() = default;
+
+// CHECK-LABEL: define
+// CHECK-LABEL: define
+void func(foo);
+void f15(foo *f) {
+ func(
+// CHECK: getelementptr {{.*}}, !dbg [[DBG_F15:![0-9]*]]
+#line 1700
+ f[3]);
+}
+
+// CHECK-LABEL: define
+void f16(__complex float f) {
+ __complex float g = //
+// CHECK: add {{.*}}, !dbg [[DBG_F16:![0-9]*]]
+#line 1800
+ f + 1;
+}
+
+// CHECK-LABEL: define
+void f17(int *x) {
+ 1,
+// CHECK: getelementptr {{.*}}, !dbg [[DBG_F17:![0-9]*]]
+#line 1900
+ x[1];
+}
+
+// CHECK-LABEL: define
+void f18(int a, int b) {
+// CHECK: icmp {{.*}}, !dbg [[DBG_F18_1:![0-9]*]]
+// CHECK: br {{.*}}, !dbg [[DBG_F18_2:![0-9]*]]
+#line 2000
+ if (a //
+ && //
+ b)
+ ;
+}
+
+// CHECK-LABEL: define
+void f19(int a, int b) {
+// CHECK: icmp {{.*}}, !dbg [[DBG_F19_1:![0-9]*]]
+// CHECK: br {{.*}}, !dbg [[DBG_F19_2:![0-9]*]]
+#line 2100
+ if (a //
+ || //
+ b)
+ ;
+}
+
+// CHECK-LABEL: define
+void f20(int a, int b, int c) {
+// CHECK: icmp {{.*}}, !dbg [[DBG_F20_1:![0-9]*]]
+// FIXME: Conditional operator's exprloc should be the '?' not the start of the
+// expression, then this would go in the right place. (but adding getExprLoc to
+// the ConditionalOperator breaks the ARC migration tool - need to investigate
+// further).
+// CHECK: br {{.*}}, !dbg [[DBG_F20_1]]
+#line 2200
+ if (a //
+ ? //
+ b : c)
+ ;
+}
+
+// CHECK-LABEL: define
+int f21_a(int = 0);
+void f21_b(int = f21_a());
+void f21() {
+// CHECK: call {{.*}}f21_b{{.*}}, !dbg [[DBG_F21:![0-9]*]]
+#line 2300
+ f21_b();
+}
+
+// CHECK-LABEL: define
+struct f22_dtor {
+ ~f22_dtor();
+};
+void f22() {
+ {
+ f22_dtor f;
+ src();
+// CHECK: invoke {{.*}}src
+// CHECK: call {{.*}}, !dbg [[DBG_F22:![0-9]*]]
+// CHECK: call {{.*}}, !dbg [[DBG_F22]]
+#line 2400
+ }
+}
+
+// CHECK-LABEL: define
+struct f23_struct {
+};
+f23_struct f23_a();
+void f23_b(f23_struct = f23_a());
+void f23() {
+// CHECK: call {{.*}}f23_a{{.*}}, !dbg [[DBG_F23:![0-9]*]]
+#line 2500
+ f23_b();
+}
+
+// CHECK-LABEL: define
+void f24_a(__complex float = complex_src());
+void f24() {
+// CHECK: call {{.*}}complex_src{{.*}}, !dbg [[DBG_F24:![0-9]*]]
+#line 2600
+ f24_a();
+}
+
+// CHECK: [[DBG_F1]] = !DILocation(line: 100,
+// CHECK: [[DBG_FOO_VALUE]] = !DILocation(line: 200,
+// CHECK: [[DBG_FOO_REF]] = !DILocation(line: 202,
+// CHECK: [[DBG_FOO_COMPLEX]] = !DILocation(line: 204,
+// CHECK: [[DBG_F2]] = !DILocation(line: 300,
+// CHECK: [[DBG_F3]] = !DILocation(line: 400,
+// CHECK: [[DBG_F4]] = !DILocation(line: 500,
+// CHECK: [[DBG_F5]] = !DILocation(line: 600,
+// CHECK: [[DBG_F6]] = !DILocation(line: 700,
+// CHECK: [[DBG_F7]] = !DILocation(line: 800,
+// CHECK: [[DBG_F8]] = !DILocation(line: 900,
+// CHECK: [[DBG_F9]] = !DILocation(line: 1000,
+// CHECK: [[DBG_F10_STORE]] = !DILocation(line: 1100,
+// CHECK: [[DBG_GLBL_CTOR_B]] = !DILocation(line: 1200,
+// CHECK: [[DBG_GLBL_DTOR_B]] = !DILocation(line: 1200,
+// CHECK: [[DBG_F11]] = !DILocation(line: 1300,
+// CHECK: [[DBG_F12]] = !DILocation(line: 1400,
+// CHECK: [[DBG_F13]] = !DILocation(line: 1500,
+// CHECK: [[DBG_F14_CTOR_CALL]] = !DILocation(line: 1600,
+// CHECK: [[DBG_F15]] = !DILocation(line: 1700,
+// CHECK: [[DBG_F16]] = !DILocation(line: 1800,
+// CHECK: [[DBG_F17]] = !DILocation(line: 1900,
+// CHECK: [[DBG_F18_1]] = !DILocation(line: 2000,
+// CHECK: [[DBG_F18_2]] = !DILocation(line: 2001,
+// CHECK: [[DBG_F19_1]] = !DILocation(line: 2100,
+// CHECK: [[DBG_F19_2]] = !DILocation(line: 2101,
+// CHECK: [[DBG_F20_1]] = !DILocation(line: 2200,
+// CHECK: [[DBG_F23]] = !DILocation(line: 2500,
+// CHECK: [[DBG_F24]] = !DILocation(line: 2600,
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-loops.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-loops.cpp
new file mode 100644
index 0000000..69948ea
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-loops.cpp
@@ -0,0 +1,49 @@
+// RUN: %clang -g -gcolumn-info -std=c++11 -S -emit-llvm %s -o - | FileCheck %s
+extern int v[2];
+int a = 0, b = 0;
+int main() {
+#line 100
+ for (int x : v) {
+ if (x)
+ ++b;
+ else
+ ++a;
+ }
+
+ // CHECK: br label {{.*}}, !dbg [[DBG1:![0-9]*]], !llvm.loop [[L1:![0-9]*]]
+
+#line 200
+ while (a)
+ if (b)
+ ++b;
+ else
+ ++a;
+ // CHECK: br label {{.*}}, !dbg [[DBG2:![0-9]*]], !llvm.loop [[L2:![0-9]*]]
+
+#line 300
+ for (unsigned i = 0; i < 100; i++) {
+ a++;
+ for (int y : v)
+ ++b;
+ }
+
+ // CHECK: br label {{.*}}, !dbg [[DBG3:![0-9]*]], !llvm.loop [[L3:![0-9]*]]
+ // CHECK: br label {{.*}}, !dbg [[DBG3:![0-9]*]], !llvm.loop [[L4:![0-9]*]]
+
+
+ // CHECK-DAG: [[L1]] = distinct !{[[L1]], [[SLDBG1:![0-9]*]], [[ELDBG1:![0-9]*]]}
+ // CHECK-DAG: [[SLDBG1]] = !DILocation(line: 100, column: 3, scope: !{{.*}})
+ // CHECK-DAG: [[ELDBG1]] = !DILocation(line: 105, column: 3, scope: !{{.*}})
+
+ // CHECK-DAG: [[L2]] = distinct !{[[L2]], [[SLDBG2:![0-9]*]], [[ELDBG2:![0-9]*]]}
+ // CHECK-DAG: [[SLDBG2]] = !DILocation(line: 200, column: 3, scope: !{{.*}})
+ // CHECK-DAG: [[ELDBG2]] = !DILocation(line: 204, column: 9, scope: !{{.*}})
+
+ // CHECK-DAG: [[L3]] = distinct !{[[L3]], [[SLDBG3:![0-9]*]], [[ELDBG3:![0-9]*]]}
+ // CHECK-DAG: [[SLDBG3]] = !DILocation(line: 302, column: 5, scope: !{{.*}})
+ // CHECK-DAG: [[ELDBG3]] = !DILocation(line: 303, column: 9, scope: !{{.*}})
+ //
+ // CHECK-DAG: [[L4]] = distinct !{[[L4]], [[SLDBG4:![0-9]*]], [[ELDBG4:![0-9]*]]}
+ // CHECK-DAG: [[SLDBG4]] = !DILocation(line: 300, column: 3, scope: !{{.*}})
+ // CHECK-DAG: [[ELDBG4]] = !DILocation(line: 304, column: 3, scope: !{{.*}})
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-member-call.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-member-call.cpp
new file mode 100644
index 0000000..3b5adb8
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-member-call.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -triple x86_64-unknown_unknown -emit-llvm -debug-info-kind=standalone -dwarf-column-info %s -o - | FileCheck %s
+void ext();
+
+struct Bar {
+ void bar() { ext(); }
+};
+
+struct Foo {
+ Bar *b;
+
+ Bar *foo() { return b; }
+};
+
+void test(Foo *f) {
+ f->foo()->bar();
+}
+
+// CHECK-LABEL: @_Z4testP3Foo
+// CHECK: call {{.*}} @_ZN3Foo3fooEv{{.*}}, !dbg ![[CALL1LOC:.*]]
+// CHECK: call void @_ZN3Bar3barEv{{.*}}, !dbg ![[CALL2LOC:.*]]
+
+// CHECK: ![[CALL1LOC]] = !DILocation(line: [[LINE:[0-9]+]], column: 6,
+// CHECK: ![[CALL2LOC]] = !DILocation(line: [[LINE]], column: 13,
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-member.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-member.cpp
new file mode 100644
index 0000000..68d02526
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-member.cpp
@@ -0,0 +1,7 @@
+// FIXME: Check IR rather than asm, then triple is not needed.
+// RUN: %clang --target=%itanium_abi_triple -fverbose-asm -g -S %s -o - | grep DW_ACCESS_public
+class A {
+public:
+ int x;
+};
+A a;
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-method-nodebug.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-method-nodebug.cpp
new file mode 100644
index 0000000..0301e2f
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-method-nodebug.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited %s -o - | FileCheck %s
+
+class C {
+ void present();
+ void absent() __attribute__((nodebug));
+};
+
+C c;
+
+// CHECK-NOT: name: "absent"
+// CHECK: name: "present"
+// CHECK-NOT: name: "absent"
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-method-spec.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-method-spec.cpp
new file mode 100644
index 0000000..0c803fd
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-method-spec.cpp
@@ -0,0 +1,11 @@
+// FIXME: Check IR rather than asm, then triple is not needed.
+// RUN: %clang --target=%itanium_abi_triple -fverbose-asm -g -S %s -o - | grep DW_AT_specification
+// Radar 9254491
+class A {
+public:
+ void doSomething(int i) { ++i; }
+};
+
+void foo(A *a) {
+ a->doSomething(2);
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-method.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-method.cpp
new file mode 100644
index 0000000..af7103e
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-method.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -std=c++11 -debug-info-kind=limited %s -o - | FileCheck %s
+// CHECK: !DIDerivedType(tag: DW_TAG_ptr_to_member_type
+// CHECK: ![[A:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_class_type, name: "A",{{.*}} identifier: "_ZTS1A")
+// CHECK: !DISubprogram(name: "foo", linkageName: "_ZN1A3fooEiS_3$_0"
+// CHECK-SAME: DIFlagProtected
+// CHECK: ![[THISTYPE:[0-9]+]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[A]]
+// CHECK-SAME: DIFlagArtificial
+// CHECK: !DIDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: ![[MEMFUNTYPE:[0-9]+]]
+// CHECK: ![[MEMFUNTYPE]] = !DISubroutineType({{(cc: DW_CC_BORLAND_thiscall, )?}}types: ![[MEMFUNARGS:[0-9]+]])
+// CHECK: ![[MEMFUNARGS]] = {{.*}}, ![[THISTYPE]],
+// CHECK: !DILocalVariable(name: "this", arg: 1
+// CHECK: !DILocalVariable(arg: 2
+// CHECK: !DILocalVariable(arg: 3
+// CHECK: !DILocalVariable(arg: 4
+union {
+ int a;
+ float b;
+} u;
+
+class A {
+protected:
+ void foo(int, A, decltype(u));
+ void bar();
+};
+
+void A::foo(int, A, decltype(u)) {
+}
+
+A a;
+
+int A::*x = 0;
+int (A::*y)(int) = 0;
+
+void A::bar() { foo(0, *this, u); }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-method2.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-method2.cpp
new file mode 100644
index 0000000..4066436
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-method2.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -x c++ -debug-info-kind=limited -S -emit-llvm < %s | FileCheck %s
+// rdar://10336845
+// Preserve type qualifiers in -flimit-debug-info mode.
+
+// CHECK: DW_TAG_const_type
+class A {
+public:
+ int bar(int arg) const;
+};
+
+int A::bar(int arg) const{
+ return arg+2;
+}
+
+int main() {
+ A a;
+ int i = a.bar(2);
+ return i;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-ms-abi.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-ms-abi.cpp
new file mode 100644
index 0000000..0ce13a0
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-ms-abi.cpp
@@ -0,0 +1,54 @@
+// RUN: %clang_cc1 %s -triple=i686-pc-windows-msvc -debug-info-kind=limited -gcodeview -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=i686-pc-windows-msvc -debug-info-kind=limited -gcodeview -gcodeview-ghash -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,GHASH
+
+// Tests that certain miscellaneous features work in the MS ABI.
+
+struct Foo {
+ virtual void f();
+ virtual void g();
+ virtual void h();
+ static void i(int, int);
+ struct Nested {};
+};
+Foo f;
+Foo::Nested n;
+
+// CHECK: ![[Nested:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Nested",
+// CHECK-SAME: identifier: ".?AUNested@Foo@@"
+
+// CHECK: ![[Foo:[^ ]*]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo",
+// CHECK-SAME: elements: ![[elements:[0-9]+]]
+// CHECK-SAME: identifier: ".?AUFoo@@"
+
+// CHECK: ![[elements]] = !{![[vshape:[0-9]+]], ![[vptr:[0-9]+]], ![[Nested]], ![[f:[0-9]+]], ![[g:[0-9]+]], ![[h:[0-9]+]], ![[i:[0-9]+]]}
+
+// CHECK: ![[vshape]] = !DIDerivedType(tag: DW_TAG_pointer_type, name: "__vtbl_ptr_type", baseType: null, size: 96)
+
+// CHECK: ![[vptr]] = !DIDerivedType(tag: DW_TAG_member, name: "_vptr$Foo",
+// CHECK-SAME: baseType: ![[vptr_ty:[0-9]+]],
+
+// CHECK: ![[vptr_ty]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[vshape]], size: 32
+
+// CHECK: ![[f]] = !DISubprogram(name: "f",
+// CHECK-SAME: containingType: ![[Foo]], virtualIndex: 0,
+// CHECK-SAME: flags: DIFlagPrototyped | DIFlagIntroducedVirtual,
+// CHECK-SAME: spFlags: DISPFlagVirtual
+
+// CHECK: ![[g]] = !DISubprogram(name: "g",
+// CHECK-SAME: containingType: ![[Foo]], virtualIndex: 1,
+// CHECK-SAME: flags: DIFlagPrototyped | DIFlagIntroducedVirtual,
+// CHECK-SAME: spFlags: DISPFlagVirtual
+
+// CHECK: ![[h]] = !DISubprogram(name: "h",
+// CHECK-SAME: containingType: ![[Foo]], virtualIndex: 2,
+// CHECK-SAME: flags: DIFlagPrototyped | DIFlagIntroducedVirtual,
+// CHECK-SAME: spFlags: DISPFlagVirtual
+
+// CHECK: ![[i]] = !DISubprogram(name: "i",
+// CHECK-SAME: flags: DIFlagPrototyped | DIFlagStaticMember
+// CHECK-NEXT: ![[dummy:[0-9]+]] = !DISubroutineType(types: ![[Signature:[0-9]+]])
+// CHECK: ![[Signature]] = !{null, ![[BasicInt:[0-9]+]], ![[BasicInt]]}
+// CHECK: ![[BasicInt]] = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+
+// CHECK: !{{[0-9]+}} = !{i32 2, !"CodeView", i32 1}
+// GHASH: !{{[0-9]+}} = !{i32 2, !"CodeViewGHash", i32 1}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-ms-anonymous-tag.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-ms-anonymous-tag.cpp
new file mode 100644
index 0000000..5e2cb21
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-ms-anonymous-tag.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -triple x86_64-pc-win32 -debug-info-kind=limited -gcodeview %s -emit-llvm -o - | FileCheck %s
+
+typedef struct {
+} test1;
+
+test1 gv1;
+
+struct {
+} test2;
+void *use_test2 = &test2;
+
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "<unnamed-type-test2>"
+
+typedef struct {
+} *test3;
+test3 gv3;
+void *use_test3 = &gv3;
+
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "<unnamed-type-test3>"
+
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "test1"
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-ms-bitfields.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-ms-bitfields.cpp
new file mode 100644
index 0000000..e423301
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-ms-bitfields.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -triple x86_64-pc-win32 -debug-info-kind=limited -gcodeview %s -emit-llvm -o - | FileCheck %s
+
+#pragma pack(1)
+struct S {
+ char : 8;
+ short : 8;
+ short x : 8;
+} s;
+
+// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "x", {{.*}}, size: 8, offset: 16, flags: DIFlagBitField, extraData: i64 8)
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-ms-dtor-thunks.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-ms-dtor-thunks.cpp
new file mode 100644
index 0000000..88449c8
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-ms-dtor-thunks.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -triple i686--windows -emit-llvm -debug-info-kind=line-tables-only -x c++ %s -fms-extensions -o - | FileCheck %s
+// RUN: %clang_cc1 -triple i686--windows -emit-llvm -debug-info-kind=line-directives-only -x c++ %s -fms-extensions -o - | FileCheck %s
+
+struct __declspec(dllexport) S { virtual ~S(); };
+struct __declspec(dllexport) T { virtual ~T(); };
+struct __declspec(dllexport) U : S, T { virtual ~U(); };
+
+// CHECK-LABEL: define {{.*}} @"??_GS@@UAEPAXI@Z"
+// CHECK: call x86_thiscallcc void @"??1S@@UAE@XZ"(%struct.S* %this1){{.*}}!dbg !{{[0-9]+}}
+
+// CHECK-LABEL: define {{.*}} @"??_GT@@UAEPAXI@Z"
+// CHECK: call x86_thiscallcc void @"??1T@@UAE@XZ"(%struct.T* %this1){{.*}}!dbg !{{[0-9]+}}
+
+// CHECK-LABEL: define {{.*}} @"??_GU@@UAEPAXI@Z"
+// CHECK: call x86_thiscallcc void @"??1U@@UAE@XZ"(%struct.U* %this1){{.*}}!dbg !{{[0-9]+}}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-ms-ptr-to-member.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-ms-ptr-to-member.cpp
new file mode 100644
index 0000000..1f4c9048
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-ms-ptr-to-member.cpp
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -triple x86_64-windows -debug-info-kind=limited -gcodeview %s -emit-llvm -o - | FileCheck %s
+
+// Test member pointer inheritance models.
+
+struct A { int a; };
+struct B { int b; };
+struct C : A, B { int c; };
+struct D : virtual C { int d; };
+struct E;
+int A::*pmd_a;
+int C::*pmd_b;
+int D::*pmd_c;
+int E::*pmd_d;
+void (A::*pmf_a)();
+void (C::*pmf_b)();
+void (D::*pmf_c)();
+void (E::*pmf_d)();
+
+// Test incomplete MPTs, which don't have inheritance models.
+
+struct Incomplete;
+int Incomplete::**ppmd;
+void (Incomplete::**ppmf)();
+
+// CHECK: distinct !DIGlobalVariable(name: "pmd_a", {{.*}} type: ![[pmd_a:[^, ]*]], {{.*}})
+// CHECK: distinct !DIGlobalVariable(name: "pmd_b", {{.*}} type: ![[pmd_b:[^, ]*]], {{.*}})
+// CHECK: ![[pmd_b]] = !DIDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: !{{.*}}, size: 32, flags: DIFlagMultipleInheritance, {{.*}})
+// CHECK: distinct !DIGlobalVariable(name: "pmd_c", {{.*}} type: ![[pmd_c:[^, ]*]], {{.*}})
+// CHECK: ![[pmd_c]] = !DIDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: !{{.*}}, size: 64, flags: DIFlagVirtualInheritance, {{.*}})
+// CHECK: distinct !DIGlobalVariable(name: "pmd_d", {{.*}} type: ![[pmd_d:[^, ]*]], {{.*}})
+// CHECK: ![[pmd_d]] = !DIDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: !{{.*}}, size: 96,
+// CHECK-NOT: flags:
+// CHECK-SAME: ){{$}}
+
+// CHECK: distinct !DIGlobalVariable(name: "pmf_a", {{.*}} type: ![[pmf_a:[^, ]*]], {{.*}})
+// CHECK: ![[pmf_a]] = !DIDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: !{{.*}}, size: 64, flags: DIFlagSingleInheritance, {{.*}})
+// CHECK: distinct !DIGlobalVariable(name: "pmf_b", {{.*}} type: ![[pmf_b:[^, ]*]], {{.*}})
+// CHECK: ![[pmf_b]] = !DIDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: !{{.*}}, size: 128, flags: DIFlagMultipleInheritance, {{.*}})
+// CHECK: distinct !DIGlobalVariable(name: "pmf_c", {{.*}} type: ![[pmf_c:[^, ]*]], {{.*}})
+// CHECK: ![[pmf_c]] = !DIDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: !{{.*}}, size: 128, flags: DIFlagVirtualInheritance, {{.*}})
+// CHECK: distinct !DIGlobalVariable(name: "pmf_d", {{.*}} type: ![[pmf_d:[^, ]*]], {{.*}})
+// CHECK: ![[pmf_d]] = !DIDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: !{{.*}}, size: 192,
+// CHECK-NOT: flags:
+// CHECK-SAME: ){{$}}
+
+// CHECK: distinct !DIGlobalVariable(name: "ppmd", {{.*}} type: ![[ppmd:[^, ]*]], {{.*}})
+// CHECK: ![[ppmd]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[ppmd2:[^ ]*]], size: 64)
+// CHECK: ![[ppmd2]] = !DIDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: !{{[0-9]*}}, extraData: !{{[0-9]*}}){{$}}
+// CHECK: distinct !DIGlobalVariable(name: "ppmf", {{.*}} type: ![[ppmf:[^, ]*]], {{.*}})
+// CHECK: ![[ppmf]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[ppmf2:[^ ]*]], size: 64)
+// CHECK: ![[ppmf2]] = !DIDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: !{{[0-9]*}}, extraData: !{{[0-9]*}}){{$}}
+
+// CHECK: ![[pmd_a]] = !DIDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: !{{.*}}, size: 32, flags: DIFlagSingleInheritance, {{.*}})
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-ms-vbase.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-ms-vbase.cpp
new file mode 100644
index 0000000..04c9a6d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-ms-vbase.cpp
@@ -0,0 +1,68 @@
+// RUN: %clang_cc1 %s -triple=i686-pc-windows-msvc -debug-info-kind=limited -gcodeview -emit-llvm -o - | FileCheck %s
+
+// Tests virtual bases in the MS ABI.
+
+// CHECK: ![[NoPrimaryBase:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "NoPrimaryBase",
+// CHECK-SAME: elements: ![[elements:[0-9]+]]
+
+// CHECK: ![[elements]] = !{![[NoPrimaryBase_base:[0-9]+]]}
+
+// CHECK: ![[NoPrimaryBase_base]] = !DIDerivedType(tag: DW_TAG_inheritance, scope: ![[NoPrimaryBase]],
+// CHECK-SAME: baseType: ![[HasVirtualMethod:[0-9]+]], offset: 4, flags: DIFlagVirtual, extraData: i32 0)
+
+// CHECK: ![[HasVirtualMethod]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "HasVirtualMethod"
+
+// CHECK: ![[HasPrimaryBase:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "HasPrimaryBase",
+// CHECK-SAME: elements: ![[elements:[0-9]+]]
+
+// CHECK: ![[elements]] = !{![[SecondaryVTable_base:[0-9]+]], ![[HasVirtualMethod_base:[0-9]+]], ![[vshape:[0-9]+]]}
+
+// CHECK: ![[SecondaryVTable_base]] = !DIDerivedType(tag: DW_TAG_inheritance, scope: ![[HasPrimaryBase]],
+// CHECK-SAME: baseType: ![[SecondaryVTable:[0-9]+]], offset: 4, flags: DIFlagVirtual, extraData: i32 4)
+
+// CHECK: ![[SecondaryVTable]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "SecondaryVTable"
+
+// CHECK: ![[HasVirtualMethod_base]] = !DIDerivedType(tag: DW_TAG_inheritance, scope: ![[HasPrimaryBase]], baseType: ![[HasVirtualMethod]], extraData: i32 0)
+
+// CHECK: ![[HasIndirectVirtualBase:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "HasIndirectVirtualBase"
+// CHECK-SAME: elements: ![[elements:[0-9]+]]
+
+// CHECK: !DIDerivedType(tag: DW_TAG_inheritance, scope: ![[HasIndirectVirtualBase]], baseType: ![[HasPrimaryBase]]
+// CHECK-NOT: DIFlagIndirectVirtualBase
+// CHECK-SAME: )
+
+// CHECK: !DIDerivedType(tag: DW_TAG_inheritance, scope: ![[HasIndirectVirtualBase]], baseType: ![[SecondaryVTable]]
+// CHECK-SAME: flags:
+// CHECK-SAME: DIFlagIndirectVirtualBase
+
+// CHECK: ![[DynamicNoVFPtr:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "DynamicNoVFPtr",
+// CHECK-SAME: elements: ![[elements:[0-9]+]]
+
+// CHECK: ![[elements]] = !{![[POD_base:[0-9]+]]}
+
+// CHECK: ![[POD_base]] = !DIDerivedType(tag: DW_TAG_inheritance, scope: ![[DynamicNoVFPtr]],
+// CHECK-SAME: baseType: ![[POD:[0-9]+]], offset: 4, flags: DIFlagVirtual, extraData: i32 0)
+
+// CHECK: ![[POD]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "POD"
+
+struct POD { int pod; };
+
+struct DynamicNoVFPtr : virtual POD { };
+
+DynamicNoVFPtr dynamic_no_vfptr;
+
+struct HasVirtualMethod { virtual void f(); };
+
+struct NoPrimaryBase : virtual HasVirtualMethod { };
+
+NoPrimaryBase no_primary_base;
+
+struct SecondaryVTable { virtual void g(); };
+
+struct HasPrimaryBase : virtual SecondaryVTable, HasVirtualMethod { };
+
+HasPrimaryBase has_primary_base;
+
+struct HasIndirectVirtualBase : public HasPrimaryBase {};
+
+HasIndirectVirtualBase has_indirect_virtual_base;
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-namespace.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-namespace.cpp
new file mode 100644
index 0000000..be88fed
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-namespace.cpp
@@ -0,0 +1,135 @@
+// RUN: %clang_cc1 -std=c++11 -debug-info-kind=limited -S -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -debug-info-kind=line-tables-only -S -emit-llvm %s -o - | FileCheck -check-prefix=CHECK-GMLT %s
+// RUN: %clang_cc1 -std=c++11 -debug-info-kind=line-directives-only -S -emit-llvm %s -o - | FileCheck -check-prefix=CHECK-GMLI %s
+// RUN: %clang_cc1 -std=c++11 -debug-info-kind=standalone -S -emit-llvm %s -o - | FileCheck -check-prefix=CHECK-NOLIMIT %s
+
+namespace A {
+#line 1 "foo.cpp"
+namespace B {
+extern int i;
+int f1() { return 0; }
+void f1(int) { }
+struct foo;
+struct bar { };
+typedef bar baz;
+extern int var_decl;
+void func_decl(void);
+extern int var_fwd;
+void func_fwd(void);
+}
+}
+namespace A {
+using namespace B;
+}
+
+using namespace A;
+namespace E = A;
+int B::i = f1();
+int func(bool b) {
+ if (b) {
+ using namespace A::B;
+ return i;
+ }
+ using namespace A;
+ using B::foo;
+ using B::bar;
+ using B::f1;
+ using B::i;
+ using B::baz;
+ namespace X = A;
+ namespace Y = X;
+ using B::var_decl;
+ using B::func_decl;
+ using B::var_fwd;
+ using B::func_fwd;
+ return i + X::B::i + Y::B::i;
+}
+
+namespace A {
+using B::i;
+namespace B {
+int var_fwd = i;
+}
+inline namespace I {
+int var_i;
+}
+}
+namespace {
+int anonymous;
+}
+void B::func_fwd() {
+ anonymous = 0;
+}
+
+namespace C {
+ void c();
+}
+void C::c() {}
+
+// This should work even if 'i' and 'func' were declarations & not definitions,
+// but it doesn't yet.
+
+// CHECK: [[I:![0-9]+]] = distinct !DIGlobalVariable(name: "i",{{.*}} scope: [[NS:![0-9]+]],
+// CHECK: [[NS]] = !DINamespace(name: "B", scope: [[CTXT:![0-9]+]])
+// CHECK: [[CTXT]] = !DINamespace(name: "A", scope: null)
+// CHECK: [[FOOCPP:.*]] = !DIFile(filename: "foo.cpp"
+// CHECK: [[VAR_FWD:![0-9]+]] = distinct !DIGlobalVariable(name: "var_fwd",{{.*}} scope: [[NS]],
+// CHECK-SAME: line: 44
+// CHECK-SAME: isDefinition: true
+// CHECK: distinct !DIGlobalVariable(name: "var_i",{{.*}} scope: [[INLINE:![0-9]+]],
+// CHECK: [[INLINE]] = !DINamespace(name: "I", scope: [[CTXT]], exportSymbols: true)
+// CHECK: !DINamespace(scope: null)
+// CHECK: [[CU:![0-9]+]] = distinct !DICompileUnit(
+// CHECK-SAME: imports: [[MODULES:![0-9]*]]
+// CHECK: [[MODULES]] = !{[[M1:![0-9]+]], [[M2:![0-9]+]], [[M3:![0-9]+]], [[M4:![0-9]+]], [[M5:![0-9]+]], [[M6:![0-9]+]], [[M7:![0-9]+]], [[M8:![0-9]+]], [[M9:![0-9]+]], [[M10:![0-9]+]], [[M11:![0-9]+]], [[M12:![0-9]+]], [[M13:![0-9]+]], [[M14:![0-9]+]], [[M15:![0-9]+]], [[M16:![0-9]+]], [[M17:![0-9]+]]
+// CHECK: [[M1]] = !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[CTXT]], entity: [[NS]], file: [[FOOCPP]], line: 15)
+
+// CHECK: [[M2]] = !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[CU]], entity: [[CTXT]],
+// CHECK: [[M3]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, name: "E", scope: [[CU]], entity: [[CTXT]], file: [[FOOCPP]], line: 19)
+// CHECK: [[M4]] = !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[LEX2:![0-9]+]], entity: [[NS]], file: [[FOOCPP]], line: 23)
+// CHECK: [[LEX2]] = distinct !DILexicalBlock(scope: [[LEX1:![0-9]+]], file: [[FOOCPP]],
+// CHECK: [[LEX1]] = distinct !DILexicalBlock(scope: [[FUNC:![0-9]+]], file: [[FOOCPP]],
+
+// CHECK: [[FUNC:![0-9]+]] = distinct !DISubprogram(name: "func",{{.*}} DISPFlagDefinition
+// CHECK: [[M5]] = !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[FUNC]], entity: [[CTXT:![0-9]+]],
+// CHECK: [[M6]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[FOO:![0-9]+]], file: [[FOOCPP]], line: 27)
+// CHECK: [[FOO]] = !DICompositeType(tag: DW_TAG_structure_type, name: "foo",
+// CHECK-SAME: line: 5
+// CHECK-SAME: DIFlagFwdDecl
+// CHECK: [[M7]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[BAR:![0-9]+]]
+// CHECK: [[BAR]] = !DICompositeType(tag: DW_TAG_structure_type, name: "bar",
+// CHECK-SAME: line: 6
+// CHECK-SAME: DIFlagFwdDecl
+
+// CHECK: [[M8]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[F1:![0-9]+]]
+// CHECK: [[F1:![0-9]+]] = distinct !DISubprogram(name: "f1",{{.*}} line: 4
+// CHECK-SAME: DISPFlagDefinition
+// CHECK: [[M9]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[I]]
+// CHECK: [[M10]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[BAZ:![0-9]+]]
+// CHECK: [[BAZ]] = !DIDerivedType(tag: DW_TAG_typedef, name: "baz", scope: [[NS]], file: [[FOOCPP]],
+// CHECK-SAME: baseType: [[BAR]]
+// CHECK: [[M11]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, name: "X", scope: [[FUNC]], entity: [[CTXT]]
+// CHECK: [[M12]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, name: "Y", scope: [[FUNC]], entity: [[M11]]
+// CHECK: [[M13]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[VAR_DECL:![0-9]+]]
+// CHECK: [[VAR_DECL]] = !DIGlobalVariable(name: "var_decl", linkageName: "{{[^"]*var_decl[^"]*}}", scope: [[NS]],{{.*}} line: 8,
+// CHECK: [[M14]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[FUNC_DECL:![0-9]+]]
+// CHECK: [[FUNC_DECL]] = !DISubprogram(name: "func_decl",
+// CHECK-SAME: scope: [[NS]], file: [[FOOCPP]], line: 9
+// CHECK: [[M15]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[VAR_FWD:![0-9]+]]
+// CHECK: [[M16]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[FUNC_FWD:![0-9]+]]
+// CHECK: [[FUNC_FWD]] = distinct !DISubprogram(name: "func_fwd",{{.*}} line: 53,{{.*}} DISPFlagDefinition
+// CHECK: [[M17]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[CTXT]], entity: [[I]]
+// CHECK: distinct !DISubprogram(name: "c",{{.*}}, scope: ![[C:[0-9]+]],{{.*}}, line: 60,{{.*}} DISPFlagDefinition
+// CHECK: ![[C]] = !DINamespace(name: "C",
+
+// CHECK-GMLT: [[CU:![0-9]+]] = distinct !DICompileUnit(
+// CHECK-GMLT-SAME: emissionKind: LineTablesOnly,
+// CHECK-GMLT-NOT: imports:
+
+// CHECK-GMLI: [[CU:![0-9]+]] = distinct !DICompileUnit(
+// CHECK-GMLI-SAME: emissionKind: DebugDirectivesOnly,
+// CHECK-GMLI-NOT: imports:
+
+// CHECK-NOLIMIT: !DICompositeType(tag: DW_TAG_structure_type, name: "bar",{{.*}} line: 6,
+// CHECK-NOLIMIT-NOT: DIFlagFwdDecl
+// CHECK-NOLIMIT-SAME: ){{$}}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-nested-exprs.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-nested-exprs.cpp
new file mode 100644
index 0000000..bd70373
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-nested-exprs.cpp
@@ -0,0 +1,202 @@
+// RUN: %clang_cc1 -triple=x86_64-pc-windows-msvc -debug-info-kind=limited \
+// RUN: -std=c++11 -gcodeview -emit-llvm -o - %s \
+// RUN: | FileCheck -check-prefix=NONEST %s
+// RUN: %clang_cc1 -triple=x86_64-pc-windows-msvc -debug-info-kind=limited \
+// RUN: -std=c++11 -gcodeview -dwarf-column-info -emit-llvm -o - %s \
+// RUN: | FileCheck -check-prefix=COLUMNS %s
+// RUN: %clang_cc1 -triple=x86_64-unknown-linux-gnu -debug-info-kind=limited \
+// RUN: -std=c++11 -emit-llvm -o - %s | FileCheck -check-prefix=NESTED %s
+// RUN: %clang_cc1 -triple=x86_64-unknown-linux-gnu -debug-info-kind=limited \
+// RUN: -std=c++11 -dwarf-column-info -emit-llvm -o - %s \
+// RUN: | FileCheck -check-prefix=COLUMNS %s
+
+class Foo {
+public:
+ static Foo create();
+ void func();
+ int *begin();
+ int *end();
+};
+
+int bar(int x, int y);
+int baz(int x, int y);
+int qux(int x, int y);
+int onearg(int x);
+int noargs();
+int noargs1();
+Foo range(int x);
+
+int foo(int x, int y, int z) {
+ int a = bar(x, y) +
+ baz(x, z) +
+ qux(y, z);
+ // NONEST: call i32 @{{.*}}bar{{.*}}, !dbg ![[LOC:[0-9]+]]
+ // NONEST: call i32 @{{.*}}baz{{.*}}, !dbg ![[LOC]]
+ // NONEST: call i32 @{{.*}}qux{{.*}}, !dbg ![[LOC]]
+ // NONEST: store i32 {{.*}}, i32* %a,{{.*}} !dbg ![[LOC]]
+ // NESTED: call i32 @{{.*}}bar{{.*}}, !dbg ![[BAR:[0-9]+]]
+ // NESTED: call i32 @{{.*}}baz{{.*}}, !dbg ![[BAZ:[0-9]+]]
+ // NESTED: call i32 @{{.*}}qux{{.*}}, !dbg ![[QUX:[0-9]+]]
+ // NESTED: store i32 {{.*}}, i32* %a,{{.*}} !dbg ![[BAR]]
+ // COLUMNS: call i32 @{{.*}}bar{{.*}}, !dbg ![[BAR:[0-9]+]]
+ // COLUMNS: call i32 @{{.*}}baz{{.*}}, !dbg ![[BAZ:[0-9]+]]
+ // COLUMNS: call i32 @{{.*}}qux{{.*}}, !dbg ![[QUX:[0-9]+]]
+ // COLUMNS: store i32 {{.*}}, i32* %a,{{.*}} !dbg ![[DECLA:[0-9]+]]
+
+ int i = 1, b = 0, c = 0;
+ // NONEST: store i32 1, i32* %i,{{.*}} !dbg ![[ILOC:[0-9]+]]
+ // NONEST: store i32 0, i32* %b,{{.*}} !dbg ![[ILOC]]
+ // NONEST: store i32 0, i32* %c,{{.*}} !dbg ![[ILOC]]
+ // NESTED: store i32 1, i32* %i,{{.*}} !dbg ![[ILOC:[0-9]+]]
+ // NESTED: store i32 0, i32* %b,{{.*}} !dbg ![[ILOC]]
+ // NESTED: store i32 0, i32* %c,{{.*}} !dbg ![[ILOC]]
+ // COLUMNS: store i32 1, i32* %i,{{.*}} !dbg ![[ILOC:[0-9]+]]
+ // COLUMNS: store i32 0, i32* %b,{{.*}} !dbg ![[BLOC:[0-9]+]]
+ // COLUMNS: store i32 0, i32* %c,{{.*}} !dbg ![[CLOC:[0-9]+]]
+
+ while (i > 0) {
+ b = bar(a, b);
+ --i;
+ }
+ // NONEST: call i32 @{{.*}}bar{{.*}}, !dbg ![[WHILE1:[0-9]+]]
+ // NONEST: store i32 %{{[^,]+}}, i32* %i,{{.*}} !dbg ![[WHILE2:[0-9]+]]
+ // NESTED: call i32 @{{.*}}bar{{.*}}, !dbg ![[WHILE1:[0-9]+]]
+ // NESTED: store i32 %{{[^,]+}}, i32* %i,{{.*}} !dbg ![[WHILE2:[0-9]+]]
+ // COLUMNS: call i32 @{{.*}}bar{{.*}}, !dbg ![[WHILE1:[0-9]+]]
+ // COLUMNS: store i32 %{{[^,]+}}, i32* %i,{{.*}} !dbg ![[WHILE2:[0-9]+]]
+
+ for (i = 0; i < 1; i++) {
+ b = bar(a, b);
+ c = qux(a, c);
+ }
+ // NONEST: call i32 @{{.*}}bar{{.*}}, !dbg ![[FOR1:[0-9]+]]
+ // NONEST: call i32 @{{.*}}qux{{.*}}, !dbg ![[FOR2:[0-9]+]]
+ // NESTED: call i32 @{{.*}}bar{{.*}}, !dbg ![[FOR1:[0-9]+]]
+ // NESTED: call i32 @{{.*}}qux{{.*}}, !dbg ![[FOR2:[0-9]+]]
+ // COLUMNS: call i32 @{{.*}}bar{{.*}}, !dbg ![[FOR1:[0-9]+]]
+ // COLUMNS: call i32 @{{.*}}qux{{.*}}, !dbg ![[FOR2:[0-9]+]]
+
+ if (a < b) {
+ int t = a;
+ a = b;
+ b = t;
+ }
+ // NONEST: store i32 %{{[^,]+}}, i32* %t,{{.*}} !dbg ![[IF1:[0-9]+]]
+ // NONEST: store i32 %{{[^,]+}}, i32* %a,{{.*}} !dbg ![[IF2:[0-9]+]]
+ // NONEST: store i32 %{{[^,]+}}, i32* %b,{{.*}} !dbg ![[IF3:[0-9]+]]
+ // NESTED: store i32 %{{[^,]+}}, i32* %t,{{.*}} !dbg ![[IF1:[0-9]+]]
+ // NESTED: store i32 %{{[^,]+}}, i32* %a,{{.*}} !dbg ![[IF2:[0-9]+]]
+ // NESTED: store i32 %{{[^,]+}}, i32* %b,{{.*}} !dbg ![[IF3:[0-9]+]]
+ // COLUMNS: store i32 %{{[^,]+}}, i32* %t,{{.*}} !dbg ![[IF1:[0-9]+]]
+ // COLUMNS: store i32 %{{[^,]+}}, i32* %a,{{.*}} !dbg ![[IF2:[0-9]+]]
+ // COLUMNS: store i32 %{{[^,]+}}, i32* %b,{{.*}} !dbg ![[IF3:[0-9]+]]
+
+ int d = onearg(
+ noargs());
+ // NONEST: call i32 @{{.*}}noargs{{.*}}, !dbg ![[DECLD:[0-9]+]]
+ // NONEST: call i32 @{{.*}}onearg{{.*}}, !dbg ![[DECLD]]
+ // NONEST: store i32 %{{[^,]+}}, i32* %d,{{.*}} !dbg ![[DECLD]]
+ // NESTED: call i32 @{{.*}}noargs{{.*}}, !dbg ![[DNOARGS:[0-9]+]]
+ // NESTED: call i32 @{{.*}}onearg{{.*}}, !dbg ![[DECLD:[0-9]+]]
+ // NESTED: store i32 %{{[^,]+}}, i32* %d,{{.*}} !dbg ![[DECLD]]
+ // COLUMNS: call i32 @{{.*}}noargs{{.*}}, !dbg ![[DNOARGS:[0-9]+]]
+ // COLUMNS: call i32 @{{.*}}onearg{{.*}}, !dbg ![[DONEARG:[0-9]+]]
+ // COLUMNS: store i32 %{{[^,]+}}, i32* %d,{{.*}} !dbg ![[DECLD:[0-9]+]]
+
+ d = onearg(noargs());
+ // NONEST: call i32 @{{.*}}noargs{{.*}}, !dbg ![[SETD:[0-9]+]]
+ // NONEST: call i32 @{{.*}}onearg{{.*}}, !dbg ![[SETD]]
+ // NONEST: store i32 %{{[^,]+}}, i32* %d,{{.*}} !dbg ![[SETD]]
+ // NESTED: call i32 @{{.*}}noargs{{.*}}, !dbg ![[SETD:[0-9]+]]
+ // NESTED: call i32 @{{.*}}onearg{{.*}}, !dbg ![[SETD]]
+ // NESTED: store i32 %{{[^,]+}}, i32* %d,{{.*}} !dbg ![[SETD]]
+ // COLUMNS: call i32 @{{.*}}noargs{{.*}}, !dbg ![[SETDNOARGS:[0-9]+]]
+ // COLUMNS: call i32 @{{.*}}onearg{{.*}}, !dbg ![[SETDONEARG:[0-9]+]]
+ // COLUMNS: store i32 %{{[^,]+}}, i32* %d,{{.*}} !dbg ![[SETD:[0-9]+]]
+
+ for (const auto x : range(noargs())) noargs1();
+ // NONEST: call i32 @{{.*}}noargs{{.*}}, !dbg ![[RANGEFOR:[0-9]+]]
+ // NONEST: call {{.+}} @{{.*}}range{{.*}}, !dbg ![[RANGEFOR]]
+ // NONEST: call i32 @{{.*}}noargs1{{.*}}, !dbg ![[RANGEFOR_BODY:[0-9]+]]
+ // NESTED: call i32 @{{.*}}noargs{{.*}}, !dbg ![[RANGEFOR:[0-9]+]]
+ // NESTED: call {{.+}} @{{.*}}range{{.*}}, !dbg ![[RANGEFOR]]
+ // NESTED: call i32 @{{.*}}noargs1{{.*}}, !dbg ![[RANGEFOR_BODY:[0-9]+]]
+ // COLUMNS: call i32 @{{.*}}noargs{{.*}}, !dbg ![[RANGEFOR_NOARGS:[0-9]+]]
+ // COLUMNS: call {{.+}} @{{.*}}range{{.*}}, !dbg ![[RANGEFOR_RANGE:[0-9]+]]
+ // COLUMNS: call i32 @{{.*}}noargs1{{.*}}, !dbg ![[RANGEFOR_BODY:[0-9]+]]
+
+ if (noargs() && noargs1()) {
+ Foo::create().func();
+ }
+ // NONEST: call i32 @{{.*}}noargs{{.*}}, !dbg ![[AND:[0-9]+]]
+ // NONEST: call i32 @{{.*}}noargs1{{.*}}, !dbg ![[AND]]
+ // NONEST: call {{.+}} @{{.*}}create{{.*}}, !dbg ![[AND_BODY:[0-9]+]]
+ // NONEST: call void @{{.*}}func{{.*}}, !dbg ![[AND_BODY]]
+ // NESTED: call i32 @{{.*}}noargs{{.*}}, !dbg ![[AND:[0-9]+]]
+ // NESTED: call i32 @{{.*}}noargs1{{.*}}, !dbg ![[AND]]
+ // NESTED: call {{.+}} @{{.*}}create{{.*}}, !dbg ![[AND_BODY:[0-9]+]]
+ // NESTED: call void @{{.*}}func{{.*}}, !dbg ![[AND_BODY]]
+ // COLUMNS: call i32 @{{.*}}noargs{{.*}}, !dbg ![[ANDLHS:[0-9]+]]
+ // COLUMNS: call i32 @{{.*}}noargs1{{.*}}, !dbg ![[ANDRHS:[0-9]+]]
+ // COLUMNS: call {{.+}} @{{.*}}create{{.*}}, !dbg ![[AND_CREATE:[0-9]+]]
+ // COLUMNS: call void @{{.*}}func{{.*}}, !dbg ![[AND_FUNC:[0-9]+]]
+
+ return a -
+ (b * z);
+ // NONEST: mul nsw i32 {{.*}}, !dbg ![[RETLOC:[0-9]+]]
+ // NONEST: sub nsw i32 {{.*}}, !dbg ![[RETLOC]]
+ // NONEST: ret i32 {{.*}}, !dbg ![[RETLOC]]
+ // NESTED: mul nsw i32 {{.*}}, !dbg ![[RETMUL:[0-9]+]]
+ // NESTED: sub nsw i32 {{.*}}, !dbg ![[RETSUB:[0-9]+]]
+ // NESTED: ret i32 {{.*}}, !dbg !
+ // COLUMNS: mul nsw i32 {{.*}}, !dbg ![[RETMUL:[0-9]+]]
+ // COLUMNS: sub nsw i32 {{.*}}, !dbg ![[RETSUB:[0-9]+]]
+ // COLUMNS: ret i32 {{.*}}, !dbg !
+}
+
+// NONEST: ![[WHILE1]] = !DILocation(
+// NONEST: ![[WHILE2]] = !DILocation(
+// NONEST: ![[FOR1]] = !DILocation(
+// NONEST: ![[FOR2]] = !DILocation(
+// NONEST: ![[IF1]] = !DILocation(
+// NONEST: ![[IF2]] = !DILocation(
+// NONEST: ![[IF3]] = !DILocation(
+// NONEST: ![[RANGEFOR]] = !DILocation(
+// NONEST-SAME: line: [[RANGEFOR_LINE:[0-9]+]]
+// NONEST: ![[RANGEFOR_BODY]] = !DILocation(
+// NONEST-SAME: line: [[RANGEFOR_LINE]]
+
+// NESTED: ![[BAR]] = !DILocation(
+// NESTED: ![[BAZ]] = !DILocation(
+// NESTED: ![[QUX]] = !DILocation(
+// NESTED: ![[DECLD]] = !DILocation
+// NESTED: ![[DNOARGS]] = !DILocation
+// NESTED: ![[RANGEFOR]] = !DILocation(
+// NESTED-SAME: line: [[RANGEFOR_LINE:[0-9]+]]
+// NESTED: ![[RANGEFOR_BODY]] = !DILocation(
+// NESTED-SAME: line: [[RANGEFOR_LINE]]
+// NESTED: ![[RETSUB]] = !DILocation(
+// NESTED: ![[RETMUL]] = !DILocation(
+
+// COLUMNS: ![[DECLA]] = !DILocation(
+// COLUMNS: ![[BAR]] = !DILocation(
+// COLUMNS: ![[BAZ]] = !DILocation(
+// COLUMNS: ![[QUX]] = !DILocation(
+// COLUMNS: ![[ILOC]] = !DILocation(
+// COLUMNS: ![[BLOC]] = !DILocation(
+// COLUMNS: ![[CLOC]] = !DILocation(
+// COLUMNS: ![[DECLD]] = !DILocation(
+// COLUMNS: ![[DNOARGS]] = !DILocation(
+// COLUMNS: ![[DONEARG]] = !DILocation(
+// COLUMNS: ![[SETDNOARGS]] = !DILocation(
+// COLUMNS: ![[SETDONEARG]] = !DILocation(
+// COLUMNS: ![[SETD]] = !DILocation(
+// COLUMNS: ![[RANGEFOR_NOARGS]] = !DILocation(
+// COLUMNS: ![[RANGEFOR_RANGE]] = !DILocation(
+// COLUMNS: ![[RANGEFOR_BODY]] = !DILocation(
+// COLUMNS: ![[ANDLHS]] = !DILocation
+// COLUMNS: ![[ANDRHS]] = !DILocation
+// COLUMNS: ![[AND_CREATE]] = !DILocation
+// COLUMNS: ![[AND_FUNC]] = !DILocation
+// COLUNMS: ![[RETSUB]] = !DILocation(
+// COLUMNS: ![[RETMUL]] = !DILocation(
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-nodebug.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-nodebug.cpp
new file mode 100644
index 0000000..9f140ef
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-nodebug.cpp
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -DSETNODEBUG=0 -emit-llvm -debug-info-kind=limited %s -o - | FileCheck %s --check-prefix=YESINFO
+// RUN: %clang_cc1 -DSETNODEBUG=1 -emit-llvm -debug-info-kind=limited %s -o - | FileCheck %s --check-prefix=NOINFO
+
+#if SETNODEBUG
+#define NODEBUG __attribute__((nodebug))
+#else
+#define NODEBUG
+#endif
+
+// Const global variable. Use it so it gets emitted.
+NODEBUG static const int const_global_int_def = 1;
+void func1(int);
+void func2() { func1(const_global_int_def); }
+// YESINFO-DAG: !DIGlobalVariable(name: "const_global_int_def"
+// NOINFO-NOT: !DIGlobalVariable(name: "const_global_int_def"
+
+// Global variable with a more involved type.
+// If the variable has no debug info, the type should not appear either.
+struct S1 {
+ int a;
+ int b;
+};
+NODEBUG S1 global_struct = { 2, 3 };
+// YESINFO-DAG: !DICompositeType({{.*}} name: "S1"
+// NOINFO-NOT: !DICompositeType({{.*}} name: "S1"
+// YESINFO-DAG: !DIGlobalVariable(name: "global_struct"
+// NOINFO-NOT: !DIGlobalVariable(name: "global_struct"
+
+// Static data members. Const member needs a use.
+// Also the class as a whole needs a use, so that we produce debug info for
+// the entire class (iterating over the members, demonstrably skipping those
+// with 'nodebug').
+struct S2 {
+ NODEBUG static int static_member;
+ NODEBUG static const int static_const_member = 4;
+};
+int S2::static_member = 5;
+void func3() {
+ S2 junk;
+ func1(S2::static_const_member);
+}
+// YESINFO-DAG: !DIGlobalVariable(name: "static_member"
+// NOINFO-NOT: !DIGlobalVariable(name: "static_member"
+// YESINFO-DAG: !DIDerivedType({{.*}} name: "static_const_member"
+// NOINFO-NOT: !DIDerivedType({{.*}} name: "static_const_member"
+
+// Function-local static and auto variables.
+void func4() {
+ NODEBUG static int static_local = 6;
+ NODEBUG int normal_local = 7;
+}
+// YESINFO-DAG: !DIGlobalVariable(name: "static_local"
+// NOINFO-NOT: !DIGlobalVariable(name: "static_local"
+// YESINFO-DAG: !DILocalVariable(name: "normal_local"
+// NOINFO-NOT: !DILocalVariable(name: "normal_local"
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-nullptr.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-nullptr.cpp
new file mode 100644
index 0000000..3054ef8
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-nullptr.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -emit-llvm -std=c++11 -debug-info-kind=limited %s -o -| FileCheck %s
+
+void foo() {
+ decltype(nullptr) t = 0;
+}
+
+// CHECK: !DIBasicType(tag: DW_TAG_unspecified_type, name: "decltype(nullptr)")
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-ptr-to-member-function.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-ptr-to-member-function.cpp
new file mode 100644
index 0000000..a7e02e4
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-ptr-to-member-function.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 %s -triple x86_64-apple-darwin -debug-info-kind=limited -emit-llvm -o - | FileCheck -check-prefix=CHECK -check-prefix=DARWIN-X64 %s
+// RUN: %clang_cc1 %s -triple x86_64-pc-win32 -debug-info-kind=limited -emit-llvm -o - | FileCheck -check-prefix=CHECK -check-prefix=WIN32-X64 %s
+
+struct T {
+ int method();
+};
+
+void foo(int (T::*method)()) {}
+
+struct Incomplete;
+
+int (Incomplete::**bar)();
+// A pointer to a member function is a pair of function- and this-pointer.
+// CHECK: !DIDerivedType(tag: DW_TAG_ptr_to_member_type,
+// DARWIN-X64-SAME: size: 128
+// WIN32-X64-NOT: size:
+// CHECK-SAME: extraData: {{.*}})
+
+// CHECK: !DIDerivedType(tag: DW_TAG_ptr_to_member_type,
+// DARWIN-X64-SAME: size: 128
+// WIN32-X64-SAME: size: 64
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-qualifiers.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-qualifiers.cpp
new file mode 100644
index 0000000..c48c9b5
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-qualifiers.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -std=c++11 -emit-llvm -debug-info-kind=limited -triple x86_64-apple-darwin %s -o - | FileCheck %s
+// Test (r)value and CVR qualifiers on C++11 non-static member functions.
+class A {
+public:
+ // CHECK: !DISubprogram(name: "l",
+ // CHECK-SAME: line: [[@LINE+4]]
+ // CHECK-SAME: type: ![[PLSR:[0-9]+]]
+ // CHECK-SAME: flags: DIFlagPublic | DIFlagPrototyped | DIFlagLValueReference,
+ // CHECK: ![[PLSR]] = !DISubroutineType(flags: DIFlagLValueReference, types: ![[ARGS:[0-9]+]])
+ void l() const &;
+ // CHECK: ![[ARGS]] = !{null, ![[THIS:[0-9]+]]}
+ // CHECK: ![[THIS]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[CONST_A:[0-9]+]]
+ // CHECK: ![[CONST_A]] = !DIDerivedType(tag: DW_TAG_const_type
+ // CHECK: !DISubprogram(name: "r"
+ // CHECK-SAME: line: [[@LINE+4]]
+ // CHECK-SAME: type: ![[PRSR:[0-9]+]]
+ // CHECK-SAME: flags: DIFlagPublic | DIFlagPrototyped | DIFlagRValueReference,
+ // CHECK: ![[PRSR]] = !DISubroutineType(flags: DIFlagRValueReference, types: ![[ARGS]])
+ void r() const &&;
+};
+
+void g() {
+ A a;
+ // The type of pl is "void (A::*)() const &".
+ // CHECK: !DILocalVariable(name: "pl",
+ // CHECK-SAME: line: [[@LINE+3]]
+ // CHECK-SAME: type: ![[PL:[0-9]+]]
+ // CHECK: !DIDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: ![[PLSR]]
+ auto pl = &A::l;
+
+ // CHECK: !DILocalVariable(name: "pr",
+ // CHECK-SAME: line: [[@LINE+3]]
+ // CHECK-SAME: type: ![[PR:[0-9]+]]
+ // CHECK: !DIDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: ![[PRSR]]
+ auto pr = &A::r;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-range-for-var-names.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-range-for-var-names.cpp
new file mode 100644
index 0000000..6cd70fe
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-range-for-var-names.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited %s -o - | FileCheck %s
+
+struct vec {
+ using itr = int*;
+ itr begin() { return nullptr; }
+ itr end() { return nullptr; }
+};
+
+void test() {
+ vec as, bs, cs;
+
+ for (auto a : as)
+ for (auto b : bs)
+ for (auto c : cs) {
+ }
+}
+
+// CHECK: call void @llvm.dbg.declare(metadata %struct.vec** {{.*}}, metadata ![[RANGE1:[0-9]+]]
+// CHECK: call void @llvm.dbg.declare(metadata i32** {{.*}}, metadata ![[BEGIN1:[0-9]+]]
+// CHECK: call void @llvm.dbg.declare(metadata i32** {{.*}}, metadata ![[END1:[0-9]+]]
+// CHECK: call void @llvm.dbg.declare(metadata %struct.vec** {{.*}}, metadata ![[RANGE2:[0-9]+]]
+// CHECK: call void @llvm.dbg.declare(metadata i32** {{.*}}, metadata ![[BEGIN2:[0-9]+]]
+// CHECK: call void @llvm.dbg.declare(metadata i32** {{.*}}, metadata ![[END2:[0-9]+]]
+// CHECK: call void @llvm.dbg.declare(metadata %struct.vec** {{.*}}, metadata ![[RANGE3:[0-9]+]]
+// CHECK: call void @llvm.dbg.declare(metadata i32** {{.*}}, metadata ![[BEGIN3:[0-9]+]]
+// CHECK: call void @llvm.dbg.declare(metadata i32** {{.*}}, metadata ![[END3:[0-9]+]]
+// CHECK: ![[RANGE1]] = !DILocalVariable(name: "__range1",
+// CHECK: ![[BEGIN1]] = !DILocalVariable(name: "__begin1",
+// CHECK: ![[END1]] = !DILocalVariable(name: "__end1",
+// CHECK: ![[RANGE2]] = !DILocalVariable(name: "__range2",
+// CHECK: ![[BEGIN2]] = !DILocalVariable(name: "__begin2",
+// CHECK: ![[END2]] = !DILocalVariable(name: "__end2",
+// CHECK: ![[RANGE3]] = !DILocalVariable(name: "__range3",
+// CHECK: ![[BEGIN3]] = !DILocalVariable(name: "__begin3",
+// CHECK: ![[END3]] = !DILocalVariable(name: "__end3",
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-rvalue-ref.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-rvalue-ref.cpp
new file mode 100644
index 0000000..de0f65a
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-rvalue-ref.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -std=c++11 -emit-llvm -debug-info-kind=limited -triple x86_64-apple-darwin %s -o - | FileCheck %s
+
+extern "C" {
+extern int printf(const char * format, ...);
+}
+void foo (int &&i)
+{
+ printf("%d\n", i);
+}
+
+// CHECK: !DIDerivedType(tag: DW_TAG_rvalue_reference_type, baseType: ![[INT:[0-9]+]], size: 64)
+// CHECK: ![[INT]] = !DIBasicType(name: "int"
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-scope.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-scope.cpp
new file mode 100644
index 0000000..1124282
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-scope.cpp
@@ -0,0 +1,72 @@
+// RUN: %clang_cc1 -debug-info-kind=limited -std=c++11 -emit-llvm %s -o -| FileCheck %s
+//
+// Two variables with the same name in subsequent if staments need to be in separate scopes.
+//
+// rdar://problem/14024005
+
+int src();
+
+void f();
+
+void func() {
+ // CHECK: = !DILocalVariable(name: "i"
+ // CHECK-SAME: scope: [[IF1:![0-9]*]]
+ // CHECK-SAME: line: [[@LINE+2]]
+ // CHECK: [[IF1]] = distinct !DILexicalBlock({{.*}}line: [[@LINE+1]])
+ if (int i = src())
+ f();
+
+ // CHECK: = !DILocalVariable(name: "i"
+ // CHECK-SAME: scope: [[IF2:![0-9]*]]
+ // CHECK-SAME: line: [[@LINE+2]]
+ // CHECK: [[IF2]] = distinct !DILexicalBlock({{.*}}line: [[@LINE+1]])
+ if (int i = src()) {
+ f();
+ } else
+ f();
+
+ // CHECK: = !DILocalVariable(name: "i"
+ // CHECK-SAME: scope: [[FOR:![0-9]*]]
+ // CHECK-SAME: line: [[@LINE+2]]
+ // CHECK: [[FOR]] = distinct !DILexicalBlock({{.*}}line: [[@LINE+1]])
+ for (int i = 0;
+ // CHECK: = !DILocalVariable(name: "b"
+ // CHECK-SAME: scope: [[FOR_BODY:![0-9]*]]
+ // CHECK-SAME: line: [[@LINE+6]]
+ // CHECK: [[FOR_BODY]] = distinct !DILexicalBlock({{.*}}line: [[@LINE-4]])
+ // The scope could be located at 'bool b', but LLVM drops line information for
+ // scopes anyway, so it's not terribly important.
+ // FIXME: change the debug info schema to not include locations of scopes,
+ // since they're not used.
+ bool b = i != 10; ++i)
+ f();
+
+ // CHECK: = !DILocalVariable(name: "i"
+ // CHECK-SAME: scope: [[FOR:![0-9]*]]
+ // CHECK-SAME: line: [[@LINE+2]]
+ // CHECK: [[FOR]] = distinct !DILexicalBlock({{.*}}line: [[@LINE+1]])
+ for (int i = 0; i != 10; ++i) {
+ // FIXME: Do not include scopes that have only other scopes (and no variables
+ // or using declarations) as direct children, they just waste
+ // space/relocations/etc.
+ // CHECK: [[FOR_LOOP_INCLUDING_COND:!.*]] = distinct !DILexicalBlock(scope: [[FOR]],{{.*}} line: [[@LINE-4]])
+ // CHECK: = !DILocalVariable(name: "b"
+ // CHECK-SAME: scope: [[FOR_COMPOUND:![0-9]*]]
+ // CHECK-SAME: line: [[@LINE+2]]
+ // CHECK: [[FOR_COMPOUND]] = distinct !DILexicalBlock(scope: [[FOR_LOOP_INCLUDING_COND]],{{.*}} line: [[@LINE-8]])
+ bool b = i % 2;
+ }
+
+ int x[] = {1, 2};
+ // CHECK: = !DILocalVariable(name: "__range1"
+ // CHECK-SAME: scope: [[RANGE_FOR:![0-9]*]]
+ // CHECK-NOT: line:
+ // CHECK-SAME: ){{$}}
+ // CHECK: [[RANGE_FOR]] = distinct !DILexicalBlock({{.*}}, line: [[@LINE+1]])
+ for (int i : x) {
+ // CHECK: = !DILocalVariable(name: "i"
+ // CHECK-SAME: scope: [[RANGE_FOR_BODY:![0-9]*]]
+ // CHECK-SAME: line: [[@LINE-3]]
+ // CHECK: [[RANGE_FOR_BODY]] = distinct !DILexicalBlock(scope: [[RANGE_FOR]],{{.*}} line: [[@LINE-4]])
+ }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-scoped-class.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-scoped-class.cpp
new file mode 100644
index 0000000..de4aee9
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-scoped-class.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=standalone -std=c++11 \
+// RUN: -triple thumbv7-apple-ios %s -o - | FileCheck %s
+
+// This forward-declared scoped enum will be created while building its own
+// declcontext. Make sure it is only emitted once.
+
+struct A {
+ enum class Return;
+ Return f1();
+};
+A::Return* f2() {}
+
+// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "Return",
+// CHECK-SAME: flags: DIFlagFwdDecl,
+// CHECK-NOT: tag: DW_TAG_enumeration_type, name: "Return"
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-static-fns.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-static-fns.cpp
new file mode 100644
index 0000000..2c8ed8f
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-static-fns.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -triple x86_64-apple-darwin %s -o - | FileCheck %s
+
+namespace A {
+ static int a(int b) { return b + 4; }
+
+ int b(int c) { return c + a(c); }
+}
+
+// Verify that a is present and mangled.
+// CHECK: define internal i32 @_ZN1AL1aEi({{.*}} !dbg [[DBG:![0-9]+]]
+// CHECK: [[DBG]] = distinct !DISubprogram(name: "a", linkageName: "_ZN1AL1aEi",
+// CHECK-SAME: line: 4
+// CHECK-SAME: DISPFlagDefinition
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-static-member.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-static-member.cpp
new file mode 100644
index 0000000..702d1f8
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-static-member.cpp
@@ -0,0 +1,156 @@
+// RUN: %clangxx -target x86_64-unknown-unknown -g %s -emit-llvm -S -o - | FileCheck %s
+// RUN: %clangxx -target x86_64-unknown-unknown -g -std=c++98 %s -emit-llvm -S -o - | FileCheck %s
+// RUN: %clangxx -target x86_64-unknown-unknown -g -std=c++11 %s -emit-llvm -S -o - | FileCheck %s
+// PR14471
+
+// CHECK: @_ZN1C1aE = dso_local global i32 4, align 4, !dbg [[A:![0-9]+]]
+// CHECK: @_ZN1C1bE = dso_local global i32 2, align 4, !dbg [[B:![0-9]+]]
+// CHECK: @_ZN1C1cE = dso_local global i32 1, align 4, !dbg [[C:![0-9]+]]
+
+enum X {
+ Y
+};
+class C
+{
+ static int a;
+ const static bool const_a = true;
+protected:
+ static int b;
+#if __cplusplus >= 201103L
+ constexpr static float const_b = 3.14;
+#else
+ const static float const_b = 3.14;
+#endif
+public:
+ static int c;
+ const static int const_c = 18;
+ int d;
+ static X x_a;
+};
+
+// The definition of C::a drives the emission of class C, which is
+// why the definition of "a" comes before the declarations while
+// "b" and "c" come after.
+
+// CHECK: [[A]] = !DIGlobalVariableExpression(var: [[AV:.*]], expr: !DIExpression())
+// CHECK: [[AV]] = distinct !DIGlobalVariable(name: "a",
+// CHECK-SAME: declaration: ![[DECL_A:[0-9]+]])
+//
+// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "X"{{.*}}, identifier: "_ZTS1X")
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "anon_static_decl_struct"
+// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "anon_static_decl_var"
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "static_decl_templ<int>"
+// CHECK-NOT: DIFlagFwdDecl
+// CHECK-SAME: ){{$}}
+// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "static_decl_templ_var"
+
+int C::a = 4;
+// CHECK: [[B]] = !DIGlobalVariableExpression(var: [[BV:.*]], expr: !DIExpression())
+// CHECK: [[BV]] = distinct !DIGlobalVariable(name: "b",
+// CHECK-SAME: declaration: ![[DECL_B:[0-9]+]])
+// CHECK: ![[DECL_B]] = !DIDerivedType(tag: DW_TAG_member, name: "b"
+// CHECK-NOT: size:
+// CHECK-NOT: align:
+// CHECK-NOT: offset:
+// CHECK-SAME: flags: DIFlagProtected | DIFlagStaticMember)
+//
+// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "C"{{.*}}, identifier: "_ZTS1C")
+//
+// CHECK: ![[DECL_A]] = !DIDerivedType(tag: DW_TAG_member, name: "a"
+// CHECK-NOT: size:
+// CHECK-NOT: align:
+// CHECK-NOT: offset:
+// CHECK-SAME: flags: DIFlagStaticMember)
+//
+// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "const_a"
+// CHECK-NOT: size:
+// CHECK-NOT: align:
+// CHECK-NOT: offset:
+// CHECK-SAME: flags: DIFlagStaticMember,
+// CHECK-SAME: extraData: i1 true)
+
+// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "const_b"
+// CHECK-NOT: size:
+// CHECK-NOT: align:
+// CHECK-NOT: offset:
+// CHECK-SAME: flags: DIFlagProtected | DIFlagStaticMember,
+// CHECK-SAME: extraData: float 0x{{.*}})
+
+// CHECK: ![[DECL_C:[0-9]+]] = !DIDerivedType(tag: DW_TAG_member, name: "c"
+// CHECK-NOT: size:
+// CHECK-NOT: align:
+// CHECK-NOT: offset:
+// CHECK-SAME: flags: DIFlagPublic | DIFlagStaticMember)
+//
+// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "const_c"
+// CHECK-NOT: size:
+// CHECK-NOT: align:
+// CHECK-NOT: offset:
+// CHECK-SAME: flags: DIFlagPublic | DIFlagStaticMember,
+// CHECK-SAME: extraData: i32 18)
+//
+// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "x_a"
+// CHECK-SAME: flags: DIFlagPublic | DIFlagStaticMember)
+
+int C::b = 2;
+// CHECK: [[C]] = !DIGlobalVariableExpression(var: [[CV:.*]], expr: !DIExpression())
+// CHECK: [[CV]] = distinct !DIGlobalVariable(name: "c", {{.*}} declaration: ![[DECL_C]])
+int C::c = 1;
+
+int main()
+{
+ C instance_C;
+ instance_C.d = 8;
+ return C::c;
+}
+
+// CHECK-NOT: !DIGlobalVariable(name: "anon_static_decl_var"
+
+// Test this in an anonymous namespace to ensure the type is retained even when
+// it doesn't get automatically retained by the string type reference machinery.
+namespace {
+struct anon_static_decl_struct {
+ static const int anon_static_decl_var = 117;
+};
+}
+
+
+int ref() {
+ return anon_static_decl_struct::anon_static_decl_var;
+}
+
+template<typename T>
+struct static_decl_templ {
+ static const int static_decl_templ_var = 7;
+};
+
+template<typename T>
+const int static_decl_templ<T>::static_decl_templ_var;
+
+int static_decl_templ_ref() {
+ return static_decl_templ<int>::static_decl_templ_var;
+}
+
+// Verify that even when a static member declaration is created lazily when
+// creating the definition, the declaration line is that of the canonical
+// declaration, not the definition. Also, since we look at the canonical
+// definition, we should also correctly emit the constant value (42) into the
+// debug info.
+struct V {
+ virtual ~V(); // cause the definition of 'V' to be omitted by no-standalone-debug optimization
+ static const int const_va = 42;
+};
+// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "const_va",
+// CHECK-SAME: line: [[@LINE-3]]
+// CHECK-SAME: extraData: i32 42
+const int V::const_va;
+
+namespace x {
+struct y {
+// CHECK: !DIGlobalVariable(name: "z",
+// CHECK-SAME: scope: [[NS_X:![0-9]+]]
+// CHECK: [[NS_X]] = !DINamespace(name: "x"
+ static int z;
+};
+int y::z;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-template-array.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-template-array.cpp
new file mode 100644
index 0000000..305327b
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-template-array.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang -emit-llvm -g -S %s -o -
+// PR13531
+template <typename>
+struct unique_ptr {
+ unique_ptr() {}
+};
+
+template <unsigned>
+struct Vertex {};
+
+void crash() // Asserts
+{
+ unique_ptr<Vertex<2>[]> v = unique_ptr<Vertex<2>[]>();
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-template-deduction-guide.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-template-deduction-guide.cpp
new file mode 100644
index 0000000..26eb215
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-template-deduction-guide.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang -S -emit-llvm -target x86_64-unknown_unknown -g %s -o - -std=c++1z | FileCheck %s
+
+// Verify that we don't crash when emitting debug information for objects
+// created from a deduced template specialization.
+
+template <class T>
+struct S {
+ S(T) {}
+};
+
+// CHECK: !DIGlobalVariable(name: "s1"
+// CHECK-SAME: type: [[TYPE_NUM:![0-9]+]]
+// CHECK: !DIGlobalVariable(name: "s2"
+// CHECK-SAME: type: [[TYPE_NUM]]
+// CHECK: [[TYPE_NUM]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S<int>",
+S s1(42);
+S<int> s2(42);
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-template-explicit-specialization.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-template-explicit-specialization.cpp
new file mode 100644
index 0000000..cd51b52
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-template-explicit-specialization.cpp
@@ -0,0 +1,120 @@
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -debug-info-kind=limited %s -o - | FileCheck %s
+
+// Run again with -gline-tables-only or -gline-directives-only and verify we don't crash. We won't output
+// type info at all.
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -debug-info-kind=line-tables-only %s -o - | FileCheck %s -check-prefix LINES-ONLY
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -debug-info-kind=line-directives-only %s -o - | FileCheck %s -check-prefix LINES-ONLY
+
+// LINES-ONLY-NOT: !DICompositeType(tag: DW_TAG_structure_type
+
+// "h" is at the top because it's in the compile unit's retainedTypes: list.
+// CHECK: DICompositeType(tag: DW_TAG_structure_type, name: "h<int>"
+// CHECK-NOT: DIFlagFwdDecl
+// CHECK-SAME: ){{$}}
+
+template <typename T>
+struct a {
+};
+extern template class a<int>;
+// CHECK-NOT: DICompositeType(tag: DW_TAG_structure_type, name: "a<int>"
+
+template <typename T>
+struct b {
+};
+extern template class b<int>;
+b<int> bi;
+
+template <typename T>
+struct c {
+ void f() {}
+};
+extern template class c<int>;
+c<int> ci;
+// CHECK: DICompositeType(tag: DW_TAG_structure_type, name: "c<int>"
+// CHECK-SAME: DIFlagFwdDecl
+
+template <typename T>
+struct d {
+ void f();
+};
+extern template class d<int>;
+d<int> di;
+// CHECK: DICompositeType(tag: DW_TAG_structure_type, name: "d<int>"
+// CHECK-NOT: DIFlagFwdDecl
+// CHECK-SAME: ){{$}}
+
+template <typename T>
+struct e {
+ void f();
+};
+template <typename T>
+void e<T>::f() {
+}
+extern template class e<int>;
+e<int> ei;
+// There's no guarantee that the out of line definition will appear before the
+// explicit template instantiation definition, so conservatively emit the type
+// definition here.
+// CHECK: DICompositeType(tag: DW_TAG_structure_type, name: "e<int>"
+// CHECK-NOT: DIFlagFwdDecl
+// CHECK-SAME: ){{$}}
+
+template <typename T>
+struct f {
+ void g();
+};
+extern template class f<int>;
+template <typename T>
+void f<T>::g() {
+}
+f<int> fi;
+// CHECK: DICompositeType(tag: DW_TAG_structure_type, name: "f<int>"
+// CHECK-NOT: DIFlagFwdDecl
+// CHECK-SAME: ){{$}}
+
+template <typename T>
+struct g {
+ void f();
+};
+template <>
+void g<int>::f();
+extern template class g<int>;
+g<int> gi;
+// CHECK: DICompositeType(tag: DW_TAG_structure_type, name: "g<int>"
+// CHECK-NOT: DIFlagFwdDecl
+// CHECK-SAME: ){{$}}
+
+template <typename T>
+struct h {
+};
+template class h<int>;
+
+template <typename T>
+struct i {
+ void f() {}
+};
+template<> void i<int>::f();
+extern template class i<int>;
+i<int> ii;
+// CHECK: DICompositeType(tag: DW_TAG_structure_type, name: "i<int>"
+// CHECK-NOT: DIFlagFwdDecl
+// CHECK-SAME: ){{$}}
+
+template <typename T1, typename T2 = T1>
+struct j {
+};
+extern template class j<int>;
+j<int> jj;
+// CHECK: DICompositeType(tag: DW_TAG_structure_type, name: "j<int, int>"
+
+template <typename T>
+struct k {
+};
+template <>
+struct k<int>;
+template struct k<int>;
+// CHECK-NOT: !DICompositeType(tag: DW_TAG_structure_type, name: "k<int>"
+
+// CHECK: DICompositeType(tag: DW_TAG_structure_type, name: "b<int>"
+// CHECK-NOT: DIFlagFwdDecl
+// CHECK-SAME: ){{$}}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-template-fwd.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-template-fwd.cpp
new file mode 100644
index 0000000..8b8d29c
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-template-fwd.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin -debug-info-kind=limited -emit-llvm -o - | FileCheck %s
+// This test is for a crash when emitting debug info for not-yet-completed
+// types.
+// Test that we don't actually emit a forward decl for the offending class:
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "Derived<int>"
+// CHECK-NOT: DIFlagFwdDecl
+// CHECK-SAME: ){{$}}
+// rdar://problem/15931354
+template <class A> class Derived;
+
+template <class A> class Base {
+ static Derived<A> *create();
+};
+
+template <class A> struct Derived : Base<A> {
+};
+
+Base<int> *f;
+
+// During the instantiation of Derived<int>, Base<int> becomes required to be
+// complete - since the declaration has already been emitted (due to 'f',
+// above), we immediately try to build debug info for Base<int> which then
+// requires the (incomplete definition) of Derived<int> which is problematic.
+//
+// (if 'f' is not present, the point at which Base<int> becomes required to be
+// complete during the instantiation of Derived<int> is a no-op because
+// Base<int> was never emitted so we ignore it and carry on until we
+// wire up the base class of Derived<int> in the debug info later on)
+Derived<int> d;
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-template-limit.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-template-limit.cpp
new file mode 100644
index 0000000..172ab94
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-template-limit.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -triple %itanium_abi_triple %s -o - | FileCheck %s
+
+// Check that this pointer type is TC<int>
+// CHECK: ![[LINE:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_class_type, name: "TC<int>"{{.*}}, identifier: "_ZTS2TCIiE")
+// CHECK: !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[LINE]]
+
+template<typename T>
+class TC {
+public:
+ TC(const TC &) {}
+ TC() {}
+};
+
+TC<int> tci;
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-template-member.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-template-member.cpp
new file mode 100644
index 0000000..db6006c
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-template-member.cpp
@@ -0,0 +1,130 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -triple x86_64-apple-darwin %s -o - | FileCheck %s
+
+// CHECK: @x = global %"struct.outer<foo>::inner" zeroinitializer, align 4, !dbg [[X:![0-9]+]]
+
+struct MyClass {
+ template <int i> int add(int j) {
+ return i + j;
+ }
+ virtual void func() {
+ }
+};
+
+int add2(int x) {
+ return MyClass().add<2>(x);
+}
+
+inline int add3(int x) {
+ return MyClass().add<3>(x); // even though add<3> is ODR used, don't emit it since we don't codegen it
+}
+
+// The compile unit pulls in the global variables first.
+// CHECK: [[X]] = !DIGlobalVariableExpression(var: [[XV:.*]], expr: !DIExpression())
+// CHECK: [[XV]] = distinct !DIGlobalVariable(name: "x",
+// CHECK-SAME: type: ![[OUTER_FOO_INNER_ID:[0-9]+]]
+//
+// CHECK: {{![0-9]+}} = distinct !DIGlobalVariable(
+// CHECK-SAME: name: "var"
+// CHECK-SAME: templateParams: {{![0-9]+}}
+// CHECK: !DITemplateTypeParameter(name: "T", type: [[TY:![0-9]+]])
+// CHECK: {{![0-9]+}} = distinct !DIGlobalVariable(
+// CHECK-SAME: name: "var"
+// CHECK-SAME: templateParams: {{![0-9]+}}
+// CHECK: !DITemplateTypeParameter(name: "P", type: {{![0-9]+}})
+// CHECK: {{![0-9]+}} = distinct !DIGlobalVariable(
+// CHECK-SAME: name: "varray"
+// CHECK-SAME: templateParams: {{![0-9]+}}
+// CHECK: !DITemplateValueParameter(name: "N", type: [[TY]], value: i32 1)
+
+// CHECK: ![[OUTER_FOO_INNER_ID:[0-9]*]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "inner"{{.*}}, identifier:
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "foo"
+// CHECK-SAME: elements: [[FOO_MEM:![0-9]*]]
+// CHECK-SAME: identifier: "_ZTS3foo"
+// CHECK: [[FOO_MEM]] = !{[[FOO_FUNC:![0-9]*]]}
+// CHECK: [[FOO_FUNC]] = !DISubprogram(name: "func", linkageName: "_ZN3foo4funcEN5outerIS_E5innerE",
+// CHECK-SAME: type: [[FOO_FUNC_TYPE:![0-9]*]]
+// CHECK: [[FOO_FUNC_TYPE]] = !DISubroutineType(types: [[FOO_FUNC_PARAMS:![0-9]*]])
+// CHECK: [[FOO_FUNC_PARAMS]] = !{null, !{{[0-9]*}}, ![[OUTER_FOO_INNER_ID]]}
+
+// CHECK: [[C:![0-9]*]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "MyClass"
+// CHECK-SAME: elements: [[C_MEM:![0-9]*]]
+// CHECK-SAME: vtableHolder: [[C]]
+// CHECK-SAME: identifier: "_ZTS7MyClass")
+// CHECK: [[C_MEM]] = !{[[C_VPTR:![0-9]*]], [[C_FUNC:![0-9]*]]}
+// CHECK: [[C_VPTR]] = !DIDerivedType(tag: DW_TAG_member, name: "_vptr$MyClass"
+
+// CHECK: [[C_FUNC]] = !DISubprogram(name: "func",{{.*}} line: 9,
+
+// CHECK: !DISubprogram(name: "add<2>"
+// CHECK-SAME: scope: [[C]]
+//
+// CHECK: [[VIRT_TEMP:![0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "virt<elem>"
+// CHECK-SAME: elements: [[VIRT_MEM:![0-9]*]]
+// CHECK-SAME: vtableHolder: [[VIRT_TEMP]]
+// CHECK-SAME: templateParams: [[VIRT_TEMP_PARAM:![0-9]*]]
+// CHECK-SAME: identifier: "_ZTS4virtI4elemE"
+
+// CHECK: [[ELEM:![0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "elem"
+// CHECK-SAME: elements: [[ELEM_MEM:![0-9]*]]
+// CHECK-SAME: identifier: "_ZTS4elem"
+// CHECK: [[ELEM_MEM]] = !{[[ELEM_X:![0-9]*]]}
+// CHECK: [[ELEM_X]] = !DIDerivedType(tag: DW_TAG_member, name: "x", scope: [[ELEM]]
+// CHECK-SAME: baseType: [[VIRT_TEMP:![0-9]+]]
+
+// CHECK: [[VIRT_TEMP_PARAM]] = !{[[VIRT_T:![0-9]*]]}
+// CHECK: [[VIRT_T]] = !DITemplateTypeParameter(name: "T", type: [[ELEM]])
+
+template<typename T>
+struct outer {
+ struct inner {
+ int i;
+ };
+};
+
+struct foo {
+ void func(outer<foo>::inner);
+};
+
+inline void func() {
+ // require 'foo' to be complete before the emission of 'inner' so that, when
+ // constructing the context chain for 'x' we emit the full definition of
+ // 'foo', which requires the definition of 'inner' again
+ foo f;
+}
+
+outer<foo>::inner x;
+
+template <typename T>
+struct virt {
+ T* values;
+ virtual ~virt();
+};
+struct elem {
+ static virt<elem> x; // ensure that completing 'elem' will require/completing 'virt<elem>'
+};
+inline void f1() {
+ elem e; // ensure 'elem' is required to be complete when it is emitted as a template argument for 'virt<elem>'
+};
+void f2() {
+ virt<elem> d; // emit 'virt<elem>'
+}
+
+// Check that the member function template specialization and implicit special
+// members (the default ctor) refer to their class by scope, even though they
+// didn't appear in the class's member list (C_MEM). This prevents the functions
+// from being added to type units, while still appearing in the type
+// declaration/reference in the compile unit.
+// CHECK: !DISubprogram(name: "MyClass"
+// CHECK-SAME: scope: [[C]]
+
+template <typename T>
+T var = T();
+template <typename P>
+P var<P *> = P();
+template <typename T, int N>
+T varray[N];
+void f3() {
+ var<int> = 1;
+ var<int *> = 1;
+ varray<int, 1>[0] = 1;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-template-partial-specialization.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-template-partial-specialization.cpp
new file mode 100644
index 0000000..0435a6f
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-template-partial-specialization.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple %s -o - -debug-info-kind=standalone | FileCheck %s
+namespace __pointer_type_imp
+{
+ template <class _Tp, class _Dp, bool > struct __pointer_type1 {};
+
+ // CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "__pointer_type1<C, default_delete<C>, false>",
+ // CHECK-SAME: templateParams: ![[PARAMS:[0-9]+]]
+ // CHECK-SAME: identifier: "_ZTSN18__pointer_type_imp15__pointer_type1I1C14default_deleteIS1_ELb0EEE"
+ template <class _Tp, class _Dp> struct __pointer_type1<_Tp, _Dp, false>
+ {
+ typedef _Tp* type;
+ };
+}
+template <class _Tp, class _Dp>
+struct __pointer_type2
+{
+ // Test that the bool template type parameter is emitted.
+ //
+ // CHECK: ![[PARAMS]] = !{!{{.*}}, !{{.*}}, ![[FALSE:[0-9]+]]}
+ // CHECK: ![[FALSE]] = !DITemplateValueParameter(type: !{{[0-9]+}}, value: i8 0)
+ typedef typename __pointer_type_imp::__pointer_type1<_Tp, _Dp, false>::type type;
+};
+template <class _Tp> struct default_delete {};
+template <class _Tp, class _Dp = default_delete<_Tp> > class unique_ptr
+{
+ typedef typename __pointer_type2<_Tp, _Dp>::type pointer;
+ unique_ptr(pointer __p, _Dp __d) {}
+};
+class C {
+ unique_ptr<C> Ptr;
+};
+void foo(C &c) {
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-template-quals.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-template-quals.cpp
new file mode 100644
index 0000000..cfee78d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-template-quals.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -triple x86_64-apple-darwin %s -o - | FileCheck %s
+
+template<typename _CharT>
+struct basic_string {
+
+ basic_string&
+ assign(const _CharT* __s, const basic_string<_CharT> &x)
+ {
+ return *this;
+ }
+};
+
+void foo (const char *c) {
+ basic_string<char> str;
+ str.assign(c, str);
+}
+
+// CHECK: [[P:![0-9]*]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: [[CON:![0-9]*]]
+// CHECK: [[CON]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: [[CH:![0-9]*]]
+// CHECK: [[CH]] = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char)
+// CHECK: [[BS:.*]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "basic_string<char>"
+// CHECK-SAME: line: 4
+// CHECK-SAME: size: 8
+// CHECK: [[TYPE:![0-9]*]] = !DISubroutineType(types: [[ARGS:.*]])
+// CHECK: [[ARGS]] = !{!{{.*}}, !{{.*}}, [[P]], [[R:.*]]}
+
+// CHECK: [[R]] = !DIDerivedType(tag: DW_TAG_reference_type, baseType: [[CON2:![0-9]*]]
+// CHECK: [[CON2]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: [[BS]]
+// CHECK: !DISubprogram(name: "assign"
+// CHECK-SAME: line: 7
+// CHECK-SAME: scopeLine: 8
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-template-recursive.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-template-recursive.cpp
new file mode 100644
index 0000000..9693b38
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-template-recursive.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -triple x86_64-apple-darwin %s -o - | FileCheck %s
+
+class base { };
+
+template <class T> class foo : public base {
+ void operator=(const foo r) { }
+};
+
+class bar : public foo<void> { };
+bar filters;
+
+// For now check that it simply doesn't crash.
+// CHECK: {{.*}}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-template.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-template.cpp
new file mode 100644
index 0000000..4b330a0
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-template.cpp
@@ -0,0 +1,162 @@
+// RUN: %clang -S -emit-llvm -target x86_64-unknown_unknown -g %s -o - -std=c++11 | FileCheck %s
+
+// CHECK: @tci = dso_local global %"struct.TC<unsigned int, 2, &glb, &foo::e, &foo::f, &foo::g, 1, 2, 3>::nested" zeroinitializer, align 1, !dbg [[TCI:![0-9]+]]
+// CHECK: @tcn = dso_local global %struct.TC zeroinitializer, align 1, !dbg [[TCN:![0-9]+]]
+// CHECK: @nn = dso_local global %struct.NN zeroinitializer, align 1, !dbg [[NN:![0-9]+]]
+
+// CHECK: !DICompileUnit(
+// CHECK: [[EMPTY:![0-9]*]] = !{}
+
+struct foo {
+ char pad[8]; // make the member pointer to 'e' a bit more interesting (nonzero)
+ int e;
+ void f();
+ static void g();
+};
+
+typedef int foo::*foo_mem;
+
+template<typename T, T, const int *x, foo_mem a, void (foo::*b)(), void (*f)(), int ...Is>
+struct TC {
+ struct nested {
+ };
+};
+
+int glb;
+void func();
+
+// CHECK: [[TCI]] = !DIGlobalVariableExpression(var: [[TCIV:.*]], expr: !DIExpression())
+// CHECK: [[TCIV]] = distinct !DIGlobalVariable(name: "tci",
+// CHECK-SAME: type: ![[TCNESTED:[0-9]+]]
+// CHECK: ![[TCNESTED]] ={{.*}}!DICompositeType(tag: DW_TAG_structure_type, name: "nested",
+// CHECK-SAME: scope: ![[TC:[0-9]+]],
+
+// CHECK: ![[TC]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "TC<unsigned int, 2, &glb, &foo::e, &foo::f, &foo::g, 1, 2, 3>"
+// CHECK-SAME: templateParams: [[TCARGS:![0-9]*]]
+TC
+// CHECK: [[TCARGS]] = !{[[TCARG1:![0-9]*]], [[TCARG2:![0-9]*]], [[TCARG3:![0-9]*]], [[TCARG4:![0-9]*]], [[TCARG5:![0-9]*]], [[TCARG6:![0-9]*]], [[TCARG7:![0-9]*]]}
+// CHECK: [[TCARG1]] = !DITemplateTypeParameter(name: "T", type: [[UINT:![0-9]*]])
+// CHECK: [[UINT:![0-9]*]] = !DIBasicType(name: "unsigned int"
+< unsigned,
+// CHECK: [[TCARG2]] = !DITemplateValueParameter(type: [[UINT]], value: i32 2)
+ 2,
+// CHECK: [[TCARG3]] = !DITemplateValueParameter(name: "x", type: [[CINTPTR:![0-9]*]], value: i32* @glb)
+// CHECK: [[CINTPTR]] = !DIDerivedType(tag: DW_TAG_pointer_type, {{.*}}baseType: [[CINT:![0-9]+]]
+// CHECK: [[CINT]] = !DIDerivedType(tag: DW_TAG_const_type, {{.*}}baseType: [[INT:![0-9]+]]
+// CHECK: [[INT]] = !DIBasicType(name: "int"
+ &glb,
+// CHECK: [[TCARG4]] = !DITemplateValueParameter(name: "a", type: [[MEMINTPTR:![0-9]*]], value: i64 8)
+// CHECK: [[MEMINTPTR]] = !DIDerivedType(tag: DW_TAG_ptr_to_member_type, {{.*}}baseType: [[INT]], {{.*}}extraData: ![[FOO:[0-9]+]])
+//
+// We could just emit a declaration of 'foo' here, rather than the entire
+// definition (same goes for any time we emit a member (function or data)
+// pointer type)
+// CHECK: [[FOO]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "foo", {{.*}}identifier: "_ZTS3foo")
+// CHECK: !DISubprogram(name: "f", linkageName: "_ZN3foo1fEv", {{.*}}type: [[FTYPE:![0-9]*]]
+//
+// Currently Clang emits the pointer-to-member-function value, but LLVM doesn't
+// use it (GCC doesn't emit a value for pointers to member functions either - so
+// it's not clear what, if any, format would be acceptable to GDB)
+//
+// CHECK: [[FTYPE:![0-9]*]] = !DISubroutineType(types: [[FARGS:![0-9]*]])
+// CHECK: [[FARGS]] = !{null, [[FARG1:![0-9]*]]}
+// CHECK: [[FARG1]] = !DIDerivedType(tag: DW_TAG_pointer_type,
+// CHECK-SAME: baseType: ![[FOO]]
+// CHECK-NOT: line:
+// CHECK-SAME: size: 64
+// CHECK-NOT: offset: 0
+// CHECK-SAME: DIFlagArtificial
+// CHECK: [[FUNTYPE:![0-9]*]] = !DISubroutineType(types: [[FUNARGS:![0-9]*]])
+// CHECK: [[FUNARGS]] = !{null}
+ &foo::e,
+// CHECK: [[TCARG5]] = !DITemplateValueParameter(name: "b", type: [[MEMFUNPTR:![0-9]*]], value: { i64, i64 } { i64 ptrtoint (void (%struct.foo*)* @_ZN3foo1fEv to i64), i64 0 })
+// CHECK: [[MEMFUNPTR]] = !DIDerivedType(tag: DW_TAG_ptr_to_member_type, {{.*}}baseType: [[FTYPE]], {{.*}}extraData: ![[FOO]])
+ &foo::f,
+// CHECK: [[TCARG6]] = !DITemplateValueParameter(name: "f", type: [[FUNPTR:![0-9]*]], value: void ()* @_ZN3foo1gEv)
+// CHECK: [[FUNPTR]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: [[FUNTYPE]]
+ &foo::g,
+// CHECK: [[TCARG7]] = !DITemplateValueParameter(tag: DW_TAG_GNU_template_parameter_pack, name: "Is", value: [[TCARG7_VALS:![0-9]*]])
+// CHECK: [[TCARG7_VALS]] = !{[[TCARG7_1:![0-9]*]], [[TCARG7_2:![0-9]*]], [[TCARG7_3:![0-9]*]]}
+// CHECK: [[TCARG7_1]] = !DITemplateValueParameter(type: [[INT]], value: i32 1)
+ 1,
+// CHECK: [[TCARG7_2]] = !DITemplateValueParameter(type: [[INT]], value: i32 2)
+ 2,
+// CHECK: [[TCARG7_3]] = !DITemplateValueParameter(type: [[INT]], value: i32 3)
+ 3>::nested tci;
+
+// CHECK: [[TCN]] = !DIGlobalVariableExpression(var: [[TCNV:.*]], expr: !DIExpression())
+// CHECK: [[TCNV]] = distinct !DIGlobalVariable(name: "tcn"
+// CHECK-SAME: type: ![[TCNT:[0-9]+]]
+TC
+// CHECK: ![[TCNT]] ={{.*}}!DICompositeType(tag: DW_TAG_structure_type, name: "TC<int, -3, nullptr, nullptr, nullptr, nullptr>"
+// CHECK-SAME: templateParams: [[TCNARGS:![0-9]*]]
+// CHECK: [[TCNARGS]] = !{[[TCNARG1:![0-9]*]], [[TCNARG2:![0-9]*]], [[TCNARG3:![0-9]*]], [[TCNARG4:![0-9]*]], [[TCNARG5:![0-9]*]], [[TCNARG6:![0-9]*]], [[TCNARG7:![0-9]*]]}
+// CHECK: [[TCNARG1]] = !DITemplateTypeParameter(name: "T", type: [[INT]])
+<int,
+// CHECK: [[TCNARG2]] = !DITemplateValueParameter(type: [[INT]], value: i32 -3)
+ -3,
+// CHECK: [[TCNARG3]] = !DITemplateValueParameter(name: "x", type: [[CINTPTR]], value: i8 0)
+ nullptr,
+
+// The interesting null pointer: -1 for member data pointers (since they are
+// just an offset in an object, they can be zero and non-null for the first
+// member)
+
+// CHECK: [[TCNARG4]] = !DITemplateValueParameter(name: "a", type: [[MEMINTPTR]], value: i64 -1)
+ nullptr,
+//
+// In some future iteration we could possibly emit the value of a null member
+// function pointer as '{ i64, i64 } zeroinitializer' as it may be handled
+// naturally from the LLVM CodeGen side once we decide how to handle non-null
+// member function pointers. For now, it's simpler just to emit the 'i8 0'.
+//
+// CHECK: [[TCNARG5]] = !DITemplateValueParameter(name: "b", type: [[MEMFUNPTR]], value: i8 0)
+ nullptr,
+// CHECK: [[TCNARG6]] = !DITemplateValueParameter(name: "f", type: [[FUNPTR]], value: i8 0)
+ nullptr
+// CHECK: [[TCNARG7]] = !DITemplateValueParameter(tag: DW_TAG_GNU_template_parameter_pack, name: "Is", value: [[EMPTY]])
+ > tcn;
+
+template<typename>
+struct tmpl_impl {
+};
+
+template <template <typename> class tmpl, int &lvr, int &&rvr>
+struct NN {
+};
+
+// CHECK: [[NN]] = !DIGlobalVariableExpression(var: [[NNV:.*]], expr: !DIExpression())
+// CHECK: [[NNV]] = distinct !DIGlobalVariable(name: "nn"
+// CHECK-SAME: type: ![[NNT:[0-9]+]]
+
+// FIXME: these parameters should probably be rendered as 'glb' rather than
+// '&glb', since they're references, not pointers.
+// CHECK: ![[NNT]] ={{.*}}!DICompositeType(tag: DW_TAG_structure_type, name: "NN<tmpl_impl, &glb, &glb>",
+// CHECK-SAME: templateParams: [[NNARGS:![0-9]*]]
+// CHECK-SAME: identifier:
+// CHECK: [[NNARGS]] = !{[[NNARG1:![0-9]*]], [[NNARG2:![0-9]*]], [[NNARG3:![0-9]*]]}
+// CHECK: [[NNARG1]] = !DITemplateValueParameter(tag: DW_TAG_GNU_template_template_param, name: "tmpl", value: !"tmpl_impl")
+// CHECK: [[NNARG2]] = !DITemplateValueParameter(name: "lvr", type: [[INTLVR:![0-9]*]], value: i32* @glb)
+// CHECK: [[INTLVR]] = !DIDerivedType(tag: DW_TAG_reference_type, baseType: [[INT]]
+// CHECK: [[NNARG3]] = !DITemplateValueParameter(name: "rvr", type: [[INTRVR:![0-9]*]], value: i32* @glb)
+// CHECK: [[INTRVR]] = !DIDerivedType(tag: DW_TAG_rvalue_reference_type, baseType: [[INT]]
+NN<tmpl_impl, glb, glb> nn;
+
+// CHECK: ![[PADDINGATEND:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "PaddingAtEnd",
+struct PaddingAtEnd {
+ int i;
+ char c;
+};
+
+PaddingAtEnd PaddedObj = {};
+
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "PaddingAtEndTemplate<&PaddedObj>"
+// CHECK-SAME: templateParams: [[PTOARGS:![0-9]*]]
+// CHECK: [[PTOARGS]] = !{[[PTOARG1:![0-9]*]]}
+// CHECK: [[PTOARG1]] = !DITemplateValueParameter(type: [[CONST_PADDINGATEND_PTR:![0-9]*]], value: %struct.PaddingAtEnd* @PaddedObj)
+// CHECK: [[CONST_PADDINGATEND_PTR]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[PADDINGATEND]], size: 64)
+template <PaddingAtEnd *>
+struct PaddingAtEndTemplate {
+};
+
+PaddingAtEndTemplate<&PaddedObj> PaddedTemplateObj;
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-this.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-this.cpp
new file mode 100644
index 0000000..a2842d0
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-this.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang -emit-llvm -g -S %s -o - | FileCheck %s
+// Radar 9239104
+class Class
+{
+public:
+//CHECK: DW_TAG_const_type
+ int foo (int p) const {
+ return p+m_int;
+ }
+
+protected:
+ int m_int;
+};
+
+Class c;
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-thunk-msabi.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-thunk-msabi.cpp
new file mode 100644
index 0000000..3dbabaf
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-thunk-msabi.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 %s -triple i386-pc-windows-msvc19.0.0 -emit-llvm \
+// RUN: -debug-info-kind=line-tables-only -fms-extensions -o - | FileCheck %s
+class __declspec(dllexport) A {
+ A(int * = new int) {}
+};
+// CHECK: define {{.*}}void @"??_FA@@AAEXXZ"
+// CHECK-SAME: !dbg ![[SP:[0-9]+]]
+// CHECK-NOT: {{ret }}
+// CHECK: call x86_thiscallcc %class.A* @"??0A@@AAE@PAH@Z"
+// CHECK-SAME: !dbg ![[DBG:[0-9]+]]
+// CHECK: ret void, !dbg
+//
+// CHECK: ![[SP]] = distinct !DISubprogram(
+// CHECK-SAME: line: 4
+// CHECK-SAME: DIFlagArtificial
+// CHECK-SAME: DISPFlagDefinition
+// CHECK-SAME: ){{$}}
+//
+// CHECK: ![[DBG]] = !DILocation(line: 0
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-thunk.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-thunk.cpp
new file mode 100644
index 0000000..f6130cc
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-thunk.cpp
@@ -0,0 +1,277 @@
+// RUN: %clang_cc1 %s -triple=x86_64-pc-windows-msvc -debug-info-kind=limited -S -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple %itanium_abi_triple -debug-info-kind=limited -S -emit-llvm -o - | FileCheck %s -check-prefix=ITANIUM
+//
+// Validate we emit a "DIFlagThunk" flag on DISubprogram entries for thunks.
+// This flag is used for emitting S_THUNK32 symbols for CodeView debugging.
+//
+// NOTE:
+// Because thunks are compiler generated and don't exist in the source, this
+// test is dependent upon the linkage name to identify the thunk. Any changes
+// in the name mangling may require this test to be updated.
+//
+// NOTE:
+// The FileCheck directives below use CHECK-DAG because the thunks may not be
+// emitted in source order.
+//
+
+namespace Test1 {
+ struct A {
+ virtual void f();
+ };
+
+ struct B {
+ virtual void f();
+ };
+
+ struct C : A, B {
+ virtual void c();
+
+ virtual void f();
+ };
+
+// CHECK-DAG: DISubprogram{{.*}}linkageName: "?f@C@Test1@@W7EAAXXZ"{{.*}} flags: {{.*}}DIFlagThunk
+ void C::f() { }
+}
+
+namespace Test2 {
+ struct V1 { };
+ struct V2 : virtual V1 { };
+
+ struct A {
+ virtual V1 *f();
+ };
+
+ struct B : A {
+ virtual void b();
+
+ virtual V2 *f();
+ };
+
+// CHECK-DAG: DISubprogram{{.*}}linkageName: "?f@B@Test2@@QEAAPEAUV1@2@XZ"{{.*}} flags: {{.*}}DIFlagThunk
+ V2 *B::f() { return 0; }
+}
+
+namespace Test3 {
+ struct A {
+ virtual void f();
+ };
+
+ struct B {
+ virtual void f();
+ };
+
+ struct __attribute__((visibility("protected"))) C : A, B {
+ virtual void c();
+
+ virtual void f();
+ };
+
+// CHECK-DAG: DISubprogram{{.*}}linkageName: "?f@C@Test3@@W7EAAXXZ"{{.*}} flags: {{.*}}DIFlagThunk
+ void C::f() { }
+}
+
+namespace Test4 {
+ struct A {
+ virtual void f();
+ };
+
+ struct B {
+ virtual void f();
+ };
+
+ namespace {
+ struct C : A, B {
+ virtual void c();
+ virtual void f();
+ };
+ }
+ void C::c() {}
+// CHECK-DAG: DISubprogram{{.*}}linkageName: "?f@C@?A0x{{[^@]*}}@Test4@@W7EAAXXZ"{{.*}} flags: {{.*}}DIFlagThunk
+ void C::f() {}
+
+ // Force C::f to be used.
+ void f() {
+ C c;
+ c.f();
+ }
+}
+
+namespace Test5 {
+ struct X {
+ X();
+ X(const X&);
+ X &operator=(const X&);
+ ~X();
+ };
+
+ struct P {
+ P();
+ P(const P&);
+ ~P();
+ X first;
+ X second;
+ };
+
+ P getP();
+
+ struct Base1 {
+ int i;
+
+ virtual X f() { return X(); }
+ };
+
+ struct Base2 {
+ float real;
+
+ virtual X f() { return X(); }
+ };
+
+ struct Thunks : Base1, Base2 {
+ long l;
+
+ virtual X f();
+ };
+
+// CHECK-DAG: DISubprogram{{.*}}linkageName: "?f@Thunks@Test5@@WBA@EAA?AUX@2@XZ"{{.*}} flags: {{.*}}DIFlagThunk
+ X Thunks::f() { return X(); }
+}
+
+namespace Test6 {
+ struct X {
+ X();
+ X(const X&);
+ X &operator=(const X&);
+ ~X();
+ };
+
+ struct Small { short s; };
+ struct Large {
+ char array[1024];
+ };
+
+ class A {
+ protected:
+ virtual void foo() = 0;
+ };
+
+ class B : public A {
+ protected:
+ virtual void bar() = 0;
+ };
+
+ class C : public A {
+ protected:
+ virtual void baz(X, X&, _Complex float, Small, Small&, Large) = 0;
+ };
+
+ class D : public B,
+ public C {
+// CHECK-DAG: DISubprogram{{.*}}linkageName: "?foo@D@Test6@@G7EAAXXZ"{{.*}} flags: {{.*}}DIFlagThunk
+ void foo() {}
+ void bar() {}
+ void baz(X, X&, _Complex float, Small, Small&, Large);
+ };
+
+ void D::baz(X, X&, _Complex float, Small, Small&, Large) { }
+
+ void testD() { D d; }
+}
+
+namespace Test7 {
+ struct A { virtual void foo(); };
+ struct B { virtual void foo(); };
+// CHECK-DAG: DISubprogram{{.*}}linkageName: "?foo@C@Test7@@W7EAAXXZ"{{.*}} flags: {{.*}}DIFlagThunk
+ struct C : A, B { void foo() {} };
+
+ // Test later.
+ void test() {
+ C c;
+ }
+}
+
+namespace Test8 {
+ struct A { virtual A* f(); };
+ struct B : virtual A { virtual A* f(); };
+ struct C : B { virtual C* f(); };
+// CHECK-DAG: DISubprogram{{.*}}linkageName: "?f@C@Test8@@QEAAPEAUA@2@XZ"{{.*}} flags: {{.*}}DIFlagThunk
+ C* C::f() { return 0; }
+}
+
+namespace Test9 {
+ struct B1 {
+ virtual B1 &foo1();
+ };
+ struct Pad1 {
+ virtual ~Pad1();
+ };
+ struct Proxy1 : Pad1, B1 {
+ virtual ~Proxy1();
+ };
+ struct D : virtual Proxy1 {
+ virtual ~D();
+ virtual D &foo1();
+ };
+// CHECK-DAG: DISubprogram{{.*}}linkageName: "?foo1@D@Test9@@$4PPPPPPPE@A@EAAAEAUB1@2@XZ"{{.*}} flags: {{.*}}DIFlagThunk
+// CHECK-DAG: DISubprogram{{.*}}linkageName: "?foo1@D@Test9@@$4PPPPPPPE@A@EAAAEAU12@XZ"{{.*}} flags: {{.*}}DIFlagThunk
+ D& D::foo1() {
+ return *this;
+ }
+}
+
+namespace Test10 {
+ class A {
+ virtual void f();
+ };
+ class B {
+ virtual void f();
+ };
+ class C : public A, public B {
+ virtual void f();
+ };
+// CHECK-DAG: DISubprogram{{.*}}linkageName: "?f@C@Test10@@G7EAAXXZ"{{.*}} flags: {{.*}}DIFlagThunk
+ void C::f() {
+ }
+}
+
+namespace Test11 {
+ class A {
+ public:
+ virtual void f();
+ };
+
+ void test() {
+// CHECK-DAG: DISubprogram{{.*}}linkageName: "??_9A@Test11@@$BA@AA"{{.*}} flags: {{.*}}DIFlagThunk
+ void (A::*p)() = &A::f;
+ }
+}
+
+namespace Test12 {
+ struct A {
+ virtual void f();
+ };
+
+ struct B {
+ virtual void f();
+ };
+
+ struct C : A, B {
+ virtual void f();
+ };
+
+ void C::f() { }
+ // ITANIUM: define {{.*}}void @_ZThn{{[48]}}_N6Test121C1fEv
+ // ITANIUM-SAME: !dbg ![[SP:[0-9]+]]
+ // ITANIUM-NOT: {{ret }}
+ // ITANIUM: = load{{.*}} !dbg ![[DBG:[0-9]+]]
+ // ITANIUM-NOT: {{ret }}
+ // ITANIUM: ret void, !dbg ![[DBG]]
+ //
+ // ITANIUM: ![[SP]] = distinct !DISubprogram(linkageName: "_ZThn{{[48]}}_N6Test121C1fEv"
+ // ITANIUM-SAME: line: 261
+ // ITANIUM-SAME: DIFlagArtificial
+ // ITANIUM-SAME: DIFlagThunk
+ // ITANIUM-SAME: DISPFlagDefinition
+ // ITANIUM-SAME: ){{$}}
+ //
+ // ITANIUM: ![[DBG]] = !DILocation(line: 0
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-union-template.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-union-template.cpp
new file mode 100644
index 0000000..d9219fc
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-union-template.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -triple x86_64-linux-gnu %s -o - | FileCheck %s
+
+// Make sure that the union type has template parameters.
+
+namespace PR15637 {
+ template <typename T> union Value { int a; };
+ void g(float value) {
+ Value<float> tempValue;
+ }
+ Value<float> f;
+}
+
+// CHECK: !DICompositeType(tag: DW_TAG_union_type, name: "Value<float>",
+// CHECK-SAME: templateParams: [[TTPARAM:![0-9]+]]
+// CHECK-SAME: identifier: "_ZTSN7PR156375ValueIfEE"
+// CHECK: [[TTPARAM]] = !{[[PARAMS:.*]]}
+// CHECK: [[PARAMS]] = !DITemplateTypeParameter(name: "T"
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-union.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-union.cpp
new file mode 100644
index 0000000..cffe6e9
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-union.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -triple x86_64-apple-darwin -std=c++11 %s -o - | FileCheck %s
+
+union E {
+ int a;
+ float b;
+ int bb() { return a;}
+ float aa() { return b;}
+ E() { a = 0; }
+};
+
+E e;
+
+// CHECK: !DICompositeType(tag: DW_TAG_union_type, name: "E"
+// CHECK-SAME: line: 3
+// CHECK-SAME: size: 32
+// CHECK-NOT: offset:
+// CHECK-SAME: {{$}}
+// CHECK: !DISubprogram(name: "bb"{{.*}}, line: 6
+// CHECK: !DISubprogram(name: "aa"{{.*}}, line: 7
+// CHECK: !DISubprogram(name: "E"{{.*}}, line: 8
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-use-after-free.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-use-after-free.cpp
new file mode 100644
index 0000000..1001248
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-use-after-free.cpp
@@ -0,0 +1,316 @@
+// RUN: %clang_cc1 -debug-info-kind=limited -triple %itanium_abi_triple -emit-llvm-only %s
+// RUN: %clang_cc1 -debug-info-kind=limited -triple %itanium_abi_triple -emit-llvm-only -std=c++98 %s
+// RUN: %clang_cc1 -debug-info-kind=limited -triple %itanium_abi_triple -emit-llvm-only -std=c++11 %s
+// Check that we don't crash.
+// PR12305, PR12315
+
+# 1 "a.h" 3
+template < typename T1 > struct Types1
+{
+ typedef T1 Head;
+};
+template < typename > struct Types;
+template < template < typename > class Tmpl > struct TemplateSel
+{
+ template < typename T > struct Bind
+ {
+ typedef Tmpl < T > type;
+ };
+};
+template < typename > struct NoneT;
+template < template < typename > class T1, template < typename > class > struct Templates2
+{
+ typedef TemplateSel < T1 > Head;
+};
+template < template < typename > class, template < typename > class =
+ NoneT, template < typename > class = NoneT, template < typename > class =
+ NoneT > struct Templates;
+template < template < typename > class T1,
+ template < typename > class T2 > struct Templates <T1, T2 >
+{
+ typedef Templates2 < T1, T2 > type;
+};
+template < typename T > struct TypeList
+{
+ typedef Types1 < T > type;
+};
+template < template < typename > class, class TestSel,
+ typename Types > class TypeParameterizedTest
+{
+public:static bool Register ()
+ {
+ typedef typename Types::Head Type;
+ typename TestSel::template Bind < Type >::type TestClass;
+}};
+
+template < template < typename > class Fixture, typename Tests,
+ typename Types > class TypeParameterizedTestCase
+{
+public:static bool Register (char *, char *, int *)
+ {
+ typedef typename Tests::Head Head;
+ TypeParameterizedTest < Fixture, Head, Types >::Register;
+}};
+
+template < typename > class TypedTestP1
+{
+};
+
+namespace gtest_case_TypedTestP1_
+{
+ template < typename gtest_TypeParam_ > class A:TypedTestP1 <
+ gtest_TypeParam_ >
+ {
+ };
+template < typename gtest_TypeParam_ > class B:TypedTestP1 <
+ gtest_TypeParam_ >
+ {
+ };
+ typedef Templates < A >::type gtest_AllTests_;
+}
+
+template < typename > class TypedTestP2
+{
+};
+
+namespace gtest_case_TypedTestP2_
+{
+ template < typename gtest_TypeParam_ > class A:TypedTestP2 <
+ gtest_TypeParam_ >
+ {
+ };
+ typedef Templates < A >::type gtest_AllTests_;
+}
+
+bool gtest_Int_TypedTestP1 =
+ TypeParameterizedTestCase < TypedTestP1,
+ gtest_case_TypedTestP1_::gtest_AllTests_,
+ TypeList < int >::type >::Register ("Int", "TypedTestP1", 0);
+bool gtest_Int_TypedTestP2 =
+ TypeParameterizedTestCase < TypedTestP2,
+ gtest_case_TypedTestP2_::gtest_AllTests_,
+ TypeList < Types < int > >::type >::Register ("Int", "TypedTestP2", 0);
+
+template < typename _Tp > struct new_allocator
+{
+ typedef _Tp *pointer;
+ template < typename > struct rebind {
+ typedef new_allocator other;
+ };
+};
+template < typename _Tp > struct allocator:new_allocator < _Tp > {
+};
+template < typename _Tp, typename _Alloc > struct _Vector_base {
+ typedef typename _Alloc::template rebind < _Tp >::other _Tp_alloc_type;
+ struct _Vector_impl {
+ typename _Tp_alloc_type::pointer _M_end_of_storage;
+ };
+ _Vector_base () {
+ foo((int *) this->_M_impl._M_end_of_storage);
+ }
+ void foo(int *);
+ _Vector_impl _M_impl;
+};
+template < typename _Tp, typename _Alloc =
+allocator < _Tp > >struct vector:_Vector_base < _Tp, _Alloc > { };
+
+
+template < class T> struct HHH {};
+struct DDD { int x_;};
+struct Data;
+struct X1;
+struct CCC:DDD { virtual void xxx (HHH < X1 >); };
+template < class SSS > struct EEE:vector < HHH < SSS > > { };
+template < class SSS, class = EEE < SSS > >class FFF { };
+template < class SSS, class GGG = EEE < SSS > >class AAA:FFF <GGG> { };
+class BBB:virtual CCC {
+ void xxx (HHH < X1 >);
+ vector < HHH < X1 > >aaa;
+};
+class ZZZ:AAA < Data >, BBB { virtual ZZZ *ppp () ; };
+ZZZ * ZZZ::ppp () { return new ZZZ; }
+
+namespace std
+{
+ template < class, class > struct pair;
+}
+namespace __gnu_cxx {
+template < typename > class new_allocator;
+}
+namespace std {
+template < typename _Tp > class allocator:__gnu_cxx::new_allocator < _Tp > {
+};
+template < typename, typename > struct _Vector_base {
+};
+template < typename _Tp, typename _Alloc = std::allocator < _Tp > >class vector:_Vector_base < _Tp,
+ _Alloc
+ > {
+ };
+}
+
+namespace
+std {
+ template <
+ typename,
+ typename > struct unary_function;
+ template <
+ typename,
+ typename,
+ typename > struct binary_function;
+ template <
+ typename
+ _Tp > struct equal_to:
+ binary_function <
+ _Tp,
+ _Tp,
+ bool > {
+ };
+ template <
+ typename
+ _Pair > struct _Select1st:
+ unary_function <
+ _Pair,
+ typename
+ _Pair::first_type > {
+ };
+}
+# 1 "f.h" 3
+using
+std::pair;
+namespace
+__gnu_cxx {
+ template <
+ class > struct hash;
+ template <
+ class,
+ class,
+ class,
+ class,
+ class
+ _EqualKey,
+ class >
+ class
+ hashtable {
+ public:
+ typedef _EqualKey
+ key_equal;
+ typedef void key_type;
+ };
+ using
+ std::equal_to;
+ using
+ std::allocator;
+ using
+ std::_Select1st;
+ template < class _Key, class _Tp, class _HashFn =
+ hash < _Key >, class _EqualKey = equal_to < _Key >, class _Alloc =
+ allocator < _Tp > >class hash_map {
+ typedef
+ hashtable <
+ pair <
+ _Key,
+ _Tp >,
+ _Key,
+ _HashFn,
+ _Select1st <
+ pair <
+ _Key,
+ _Tp > >,
+ _EqualKey,
+ _Alloc >
+ _Ht;
+ public:
+ typedef typename _Ht::key_type key_type;
+ typedef typename
+ _Ht::key_equal
+ key_equal;
+ };
+}
+using
+__gnu_cxx::hash_map;
+class
+C2;
+template < class > class scoped_ptr {
+};
+namespace {
+class
+ AAA {
+protected:
+ virtual ~
+ AAA () {
+ }};
+}
+template < typename > class EEE;
+template < typename CCC, typename =
+typename CCC::key_equal, typename =
+EEE < CCC > >class III {
+};
+namespace
+util {
+ class
+ EEE {
+ };
+}
+namespace {
+class
+ C1:
+ util::EEE {
+ public:
+ class
+ C3:
+ AAA {
+ struct FFF;
+ typedef
+ III <
+ hash_map <
+ C2,
+ FFF > >
+ GGG;
+ GGG
+ aaa;
+ friend
+ C1;
+ };
+ void
+ HHH (C3::GGG &);
+ };
+}
+namespace
+n1 {
+ class
+ Test {
+ };
+ template <
+ typename >
+ class
+ C7 {
+ };
+ class
+ C4:
+ n1::Test {
+ vector <
+ C1::C3 * >
+ a1;
+ };
+ enum C5 { };
+ class
+ C6:
+ C4,
+ n1::C7 <
+ C5 > {
+ };
+ class
+ C8:
+ C6 {
+ };
+ class
+ C9:
+ C8 {
+ void
+ TestBody ();
+ };
+ void
+ C9::TestBody () {
+ scoped_ptr < C1::C3 > context;
+ }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-uuid.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-uuid.cpp
new file mode 100644
index 0000000..70b205a
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-uuid.cpp
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -emit-llvm -fms-extensions -triple=x86_64-pc-win32 -debug-info-kind=limited %s -o - -std=c++11 | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -fms-extensions -triple=x86_64-unknown-unknown -debug-info-kind=limited %s -o - -std=c++11 2>&1 | FileCheck %s --check-prefix=CHECK-ITANIUM
+
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "tmpl_guid2<__uuidof(uuid)>"
+// CHECK-SAME: templateParams: [[TGI2ARGS:![0-9]*]]
+// CHECK: [[TGI2ARGS]] = !{[[TGI2ARG1:![0-9]*]]}
+// CHECK: [[TGI2ARG1]] = !DITemplateValueParameter(
+// CHECK-SAME: type: [[CONST_GUID_REF:![0-9]*]]
+// CHECK-SAME: value: { i32, i16, i16, [8 x i8] }* @_GUID_12345678_1234_1234_1234_1234567890ab
+// CHECK: [[CONST_GUID_REF]] = !DIDerivedType(tag: DW_TAG_reference_type,
+// CHECK-SAME: baseType: [[CONST_GUID:![0-9]*]]
+// CHECK: [[CONST_GUID]] = !DIDerivedType(tag: DW_TAG_const_type
+// CHECK-SAME: baseType: [[GUID:![0-9]*]]
+// CHECK: [[GUID]] = !DICompositeType(tag: DW_TAG_structure_type, name: "_GUID"
+
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "tmpl_guid<&__uuidof(uuid)>"
+// CHECK-SAME: templateParams: [[TGIARGS:![0-9]*]]
+// CHECK: [[TGIARGS]] = !{[[TGIARG1:![0-9]*]]}
+// CHECK: [[TGIARG1]] = !DITemplateValueParameter(
+// CHECK-SAME: type: [[CONST_GUID_PTR:![0-9]*]]
+// CHECK-SAME: value: { i32, i16, i16, [8 x i8] }* @_GUID_12345678_1234_1234_1234_1234567890ab
+// CHECK: [[CONST_GUID_PTR]] = !DIDerivedType(tag: DW_TAG_pointer_type
+// CHECK-SAME: baseType: [[CONST_GUID:![0-9]*]]
+// CHECK-SAME: size: 64
+
+// CHECK-ITANIUM: !DICompositeType(tag: DW_TAG_structure_type, name: "tmpl_guid2<__uuidof(uuid)>"
+// CHECK-ITANIUM-SAME: identifier: "_ZTS10tmpl_guid2IXu8__uuidoft4uuidEE"
+// CHECK-ITANIUM: !DICompositeType(tag: DW_TAG_structure_type, name: "tmpl_guid<&__uuidof(uuid)>"
+// CHECK-ITANIUM-SAME: identifier: "_ZTS9tmpl_guidIXadu8__uuidoft4uuidEE"
+
+struct _GUID;
+template <const _GUID *>
+struct tmpl_guid {
+};
+
+struct __declspec(uuid("{12345678-1234-1234-1234-1234567890ab}")) uuid;
+tmpl_guid<&__uuidof(uuid)> tgi;
+
+template <const _GUID &>
+struct tmpl_guid2 {};
+tmpl_guid2<__uuidof(uuid)> tgi2;
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-varargs.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-varargs.cpp
new file mode 100644
index 0000000..7afbcd2
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-varargs.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -debug-info-kind=limited %s -o - | FileCheck %s
+
+struct A
+{
+ void a(int c, ...) {}
+};
+
+ // CHECK: !DISubprogram(name: "b", linkageName: "_Z1biz"
+ // CHECK-SAME: line: [[@LINE+2]]
+ // CHECK-SAME: type: ![[BTY:[0-9]+]]
+void b(int c, ...) {
+ // CHECK: ![[BTY]] = !DISubroutineType(types: ![[BARGS:[0-9]+]])
+ // CHECK: ![[BARGS]] = !{null, !{{[0-9]+}}, null}
+
+ // The subprogram "a" comes after "b" because the function comes later.
+ // CHECK: !DISubprogram(name: "a", linkageName: "_ZN1A1aEiz"
+ // CHECK-SAME: line: 5,
+ // CHECK-SAME: type: ![[ATY:[0-9]+]]
+ // CHECK: ![[ATY]] = !DISubroutineType(types: ![[AARGS:[0-9]+]])
+ // We no longer use an explicit unspecified parameter. Instead we use a trailing null to mean the function is variadic.
+ // CHECK: ![[AARGS]] = !{null, !{{[0-9]+}}, !{{[0-9]+}}, null}
+
+ A a;
+
+ // CHECK: !DILocalVariable(name: "fptr"
+ // CHECK-SAME: line: [[@LINE+2]]
+ // CHECK-SAME: type: ![[PST:[0-9]+]]
+ void (*fptr)(int, ...) = b;
+ // CHECK: ![[PST]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[BTY]],
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-vla.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-vla.cpp
new file mode 100644
index 0000000..73bdaf0
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-vla.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -std=c++11 -triple x86_64-unknown-unknown %s -o - | FileCheck %s
+
+
+void f(int m) {
+ int x[3][m];
+}
+
+int (*fp)(int[][*]) = nullptr;
+
+// CHECK: !DICompositeType(tag: DW_TAG_array_type,
+// CHECK-NOT: size:
+// CHECK-SAME: elements: [[ELEM_TYPE:![0-9]+]]
+// CHECK: [[ELEM_TYPE]] = !{[[NOCOUNT:.*]]}
+// CHECK: [[NOCOUNT]] = !DISubrange(count: -1)
+//
+// CHECK: [[VAR:![0-9]+]] = !DILocalVariable(name: "__vla_expr0", {{.*}}flags: DIFlagArtificial
+// CHECK: !DICompositeType(tag: DW_TAG_array_type,
+// CHECK-NOT: size:
+// CHECK-SAME: elements: [[ELEM_TYPE:![0-9]+]]
+// CHECK: [[ELEM_TYPE]] = !{[[THREE:.*]], [[VARRANGE:![0-9]+]]}
+// CHECK: [[THREE]] = !DISubrange(count: 3)
+// CHECK: [[VARRANGE]] = !DISubrange(count: [[VAR]])
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-vtable-optzn.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-vtable-optzn.cpp
new file mode 100644
index 0000000..8b49e95
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-vtable-optzn.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=standalone -triple x86_64-apple-darwin %s -o - | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=standalone -triple amd64-unknown-freebsd %s -o - | FileCheck %s
+//
+// This tests that the "emit debug info for a C++ class only in the
+// module that has its vtable" optimization is disabled by default on
+// Darwin and FreeBSD.
+//
+// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "lost"
+class A
+{
+ virtual bool f() = 0;
+ int lost;
+};
+
+class B : public A
+{
+ B *g();
+};
+
+B *B::g() {
+ return this;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-wchar.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-wchar.cpp
new file mode 100644
index 0000000..1ecdd56
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-wchar.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited %s -o -| FileCheck %s
+void foo() {
+// CHECK: !DIBasicType(name: "wchar_t"
+ const wchar_t w = L'x';
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-windows-dtor.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-windows-dtor.cpp
new file mode 100644
index 0000000..beea56c
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-windows-dtor.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple i386-unknown-windows-msvc -std=c++11 -emit-llvm -debug-info-kind=line-tables-only %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple i386-unknown-windows-msvc -std=c++11 -emit-llvm -debug-info-kind=line-directives-only %s -o - | FileCheck %s
+
+struct A {
+ virtual ~A() {}
+};
+
+struct B {
+ virtual ~B() {}
+};
+
+template<typename T>
+struct AB: A, B {
+};
+
+template struct AB<int>;
+
+// CHECK: define {{.*}}@"??_E?$AB@H@@W3AEPAXI@Z"({{.*}} !dbg [[THUNK_VEC_DEL_DTOR:![0-9]*]]
+// CHECK: call {{.*}}@"??_G?$AB@H@@UAEPAXI@Z"({{.*}}) #{{[0-9]*}}, !dbg [[THUNK_LOC:![0-9]*]]
+// CHECK: define
+
+// CHECK: [[THUNK_VEC_DEL_DTOR]] = distinct !DISubprogram
+// CHECK: [[THUNK_LOC]] = !DILocation(line: 0, scope: [[THUNK_VEC_DEL_DTOR]])
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info-zero-length-arrays.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info-zero-length-arrays.cpp
new file mode 100644
index 0000000..9f8eab6
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info-zero-length-arrays.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang -target x86_64-unknown-unknown -fverbose-asm -g -O0 -S -emit-llvm %s -o - | FileCheck %s
+// <rdar://problem/12566646>
+
+class A {
+ int x[];
+};
+A a;
+
+// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "x"
+// CHECK-SAME: baseType: [[ARRAY_TYPE:![0-9]+]]
+// CHECK: [[ARRAY_TYPE]] = !DICompositeType(tag: DW_TAG_array_type,
+// CHECK-NOT: size:
+// CHECK-SAME: elements: [[ELEM_TYPE:![0-9]+]]
+// CHECK: [[ELEM_TYPE]] = !{[[SUBRANGE:.*]]}
+// CHECK: [[SUBRANGE]] = !DISubrange(count: -1)
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-info.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-info.cpp
new file mode 100644
index 0000000..8ac4016
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-info.cpp
@@ -0,0 +1,164 @@
+// RUN: %clang_cc1 -triple x86_64-none-linux-gnu -emit-llvm -debug-info-kind=limited %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=BOTH
+// RUN: %clang_cc1 -triple i686-pc-windows-msvc -emit-llvm -debug-info-kind=limited %s -o - | FileCheck %s --check-prefix=MSVC --check-prefix=BOTH
+
+// CHECK: @_ZN6pr96081xE = global [3 x i8]* null, align 8, !dbg [[X:![0-9]+]]
+
+// CHECK: define void @_ZN7pr147634funcENS_3fooE
+// CHECK: call void @llvm.dbg.declare({{.*}}, metadata ![[F:[0-9]+]], metadata !DIExpression())
+
+// !llvm.dbg.cu pulls in globals and their types first.
+// CHECK-NOT: !DIGlobalVariable(name: "c"
+// CHECK: [[X]] = !DIGlobalVariableExpression(var: [[XV:!.*]], expr: !DIExpression())
+// CHECK: [[XV]] = distinct !DIGlobalVariable(name: "x", linkageName: "_ZN6pr96081xE"
+// CHECK-SAME: type: [[INCARRAYPTR:![0-9]*]]
+// CHECK: [[INCARRAYPTR]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: [[INCARRAY:![0-9]+]]
+// CHECK: [[INCARRAY]] = !DICompositeType(tag: DW_TAG_array_type
+// CHECK-NOT: line:
+// CHECK-NOT: size:
+// CHECK-NOT: align:
+// CHECK-NOT: offset:
+// CHECK-SAME: baseType: ![[INCTYPE:[0-9]+]]
+
+// CHECK: ![[INCTYPE]] = !DICompositeType(tag: DW_TAG_structure_type, name: "incomplete"
+// CHECK-SAME: DIFlagFwdDecl
+
+template<typename T> struct Identity {
+ typedef T Type;
+};
+
+void f(Identity<int>::Type a) {}
+void f(Identity<int> a) {}
+void f(int& a) { }
+
+template<typename T> struct A {
+ A<T> *next;
+};
+void f(A<int>) { }
+
+struct B { };
+
+void f() {
+ int B::*a = 0;
+ void (B::*b)() = 0;
+}
+
+namespace EmptyNameCrash {
+ struct A { A(); };
+ typedef struct { A x; } B;
+ B x;
+}
+
+// PR4890
+namespace PR4890 {
+ struct X {
+ ~X();
+ };
+
+ X::~X() { }
+}
+
+namespace VirtualDtor {
+ struct Y {
+ virtual ~Y();
+ };
+
+ Y::~Y() { }
+}
+
+namespace VirtualBase {
+ struct A { int a; };
+ struct B : virtual A { int b; };
+// BOTH: ![[VBASE_B:[0-9]+]] ={{.*}}!DICompositeType(tag: DW_TAG_structure_type, name: "B",{{.*}} line: [[@LINE-1]],
+// MSVC-SAME: size: 96
+// CHECK-SAME: size: 128,
+// BOTH-NOT: offset:
+// BOTH-NOT: DIFlagFwdDecl
+// BOTH-SAME: elements: [[VBASE_B_DEF:![0-9]+]]
+// BOTH: [[VBASE_B_DEF]] = !{[[VBASE_A_IN_B:![0-9]+]],
+//
+// Look for the vbtable offset of A, which should be 4 for MSVC, 24 otherwise.
+// BOTH: [[VBASE_A_IN_B]] = !DIDerivedType(tag: DW_TAG_inheritance, scope: ![[VBASE_B]],
+// BOTH-SAME: baseType: ![[VBASE_A:[0-9]+]],
+// MSVC-SAME: offset: 4,
+// CHECK-SAME: offset: 24,
+//
+// BOTH: ![[VBASE_A]] ={{.*}}!DICompositeType(tag: DW_TAG_structure_type, name: "A",
+
+ void f() {
+ B b;
+ }
+}
+
+namespace b5249287 {
+template <typename T> class A {
+ struct B;
+};
+
+class Cls {
+ template <typename T> friend class A<T>::B;
+};
+
+Cls obj;
+}
+
+// CHECK: [[FUNC:[0-9]+]] = distinct !DISubprogram(name: "func", linkageName: "_ZN7pr147634funcENS_3fooE"
+// CHECK-SAME: type: {{![0-9]+}}
+// CHECK-SAME: DISPFlagDefinition
+
+// CHECK: [[PR14763:![0-9]+]] = !DINamespace(name: "pr14763"
+namespace pr14763 {
+struct foo {
+// CHECK: ![[FOO:[0-9]+]] ={{.*}}!DICompositeType(tag: DW_TAG_structure_type, name: "foo"
+// CHECK-SAME: scope: [[PR14763]]
+// CHECK-SAME: identifier:
+ foo(const foo&);
+};
+
+// For some reason function arguments ended up down here
+// CHECK: ![[F]] = !DILocalVariable(name: "f", arg: 1, scope: ![[FUNC]]
+// CHECK-SAME: type: ![[FOO]]
+foo func(foo f) {
+ return f; // reference 'f' for now because otherwise we hit another bug
+}
+
+}
+
+void foo() {
+// CHECK: !DILocalVariable(name: "c"
+// CHECK-NOT: arg:
+// CHECK-SAME: )
+ const wchar_t c = L'x';
+ wchar_t d = c;
+}
+
+namespace pr9608 { // also pr9600
+struct incomplete;
+incomplete (*x)[3];
+}
+
+namespace pr16214 {
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "a"
+// CHECK-SAME: elements: [[A_MEM:![0-9]+]]
+// CHECK-SAME: identifier: "_ZTSN7pr162141aE"
+// CHECK: [[A_MEM]] = !{[[A_I:![0-9]*]]}
+struct a {
+// CHECK: [[A_I]] = !DIDerivedType(tag: DW_TAG_member, name: "i"
+ int i;
+};
+
+typedef a at;
+
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "b"
+// CHECK-SAME: DIFlagFwdDecl
+struct b {
+};
+
+typedef b bt;
+
+void func() {
+ at a_inst;
+ bt *b_ptr_inst;
+ const bt *b_cnst_ptr_inst;
+}
+
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-lambda-expressions.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-lambda-expressions.cpp
new file mode 100644
index 0000000..324c092
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-lambda-expressions.cpp
@@ -0,0 +1,103 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -emit-llvm -o - %s -fexceptions -std=c++11 -debug-info-kind=limited | FileCheck %s
+
+auto var = [](int i) { return i+1; };
+void *use = &var;
+
+extern "C" auto cvar = []{};
+
+int a() { return []{ return 1; }(); }
+
+int b(int x) { return [x]{return x;}(); }
+
+int c(int x) { return [&x]{return x;}(); }
+
+struct D { D(); D(const D&); int x; };
+int d(int x) { D y[10]; return [x,y] { return y[x].x; }(); }
+
+// Randomness for file. -- 6
+
+// VAR:
+// CHECK: !DIGlobalVariable(name: "var"
+// CHECK-SAME: line: [[VAR_LINE:[0-9]+]]
+// CHECK-SAME: type: ![[VAR_T:[0-9]+]]
+
+// CHECK: [[FILE:.*]] = !DIFile(filename: "{{.*}}debug-lambda-expressions.cpp",
+
+// CVAR:
+// CHECK: !DIGlobalVariable(name: "cvar"
+// CHECK-SAME: line: [[CVAR_LINE:[0-9]+]]
+// CHECK-SAME: type: ![[CVAR_T:[0-9]+]]
+// CHECK: ![[CVAR_T]] = distinct !DICompositeType(tag: DW_TAG_class_type
+// CHECK-SAME: line: [[CVAR_LINE]],
+// CHECK-SAME: elements: ![[CVAR_ARGS:[0-9]+]]
+// CHECK: ![[CVAR_ARGS]] = !{!{{[0-9]+}}}
+
+// CHECK: ![[VAR_T]] = distinct !DICompositeType(tag: DW_TAG_class_type
+// CHECK-SAME: line: [[VAR_LINE]],
+// CHECK-SAME: elements: ![[VAR_ARGS:[0-9]+]]
+// CHECK: ![[VAR_ARGS]] = !{!{{[0-9]+}}}
+
+// CHECK: ![[INT:[0-9]+]] = !DIBasicType(name: "int"
+
+// A: 10
+// CHECK: ![[A_FUNC:.*]] = distinct !DISubprogram(name: "a"{{.*}}, line: [[A_LINE:[0-9]+]]{{.*}} DISPFlagDefinition
+
+// Back to A. -- 78
+// CHECK: ![[LAM_A:.*]] = distinct !DICompositeType(tag: DW_TAG_class_type{{.*}}, scope: ![[A_FUNC]]{{.*}}, line: [[A_LINE]],
+// CHECK-SAME: elements: ![[LAM_A_ARGS:[0-9]+]]
+// CHECK: ![[LAM_A_ARGS]] = !{![[CON_LAM_A:[0-9]+]]}
+// CHECK: ![[CON_LAM_A]] = !DISubprogram(name: "operator()"
+// CHECK-SAME: scope: ![[LAM_A]]
+// CHECK-SAME: line: [[A_LINE]]
+// CHECK-SAME: DIFlagPublic
+
+// B: 14
+// CHECK: ![[B_FUNC:.*]] = distinct !DISubprogram(name: "b"{{.*}}, line: [[B_LINE:[0-9]+]]{{.*}} DISPFlagDefinition
+
+// Back to B. -- 67
+// CHECK: ![[LAM_B:.*]] = distinct !DICompositeType(tag: DW_TAG_class_type{{.*}}, scope: ![[B_FUNC]]{{.*}}, line: [[B_LINE]],
+// CHECK-SAME: elements: ![[LAM_B_ARGS:[0-9]+]]
+// CHECK: ![[LAM_B_ARGS]] = !{![[CAP_B:[0-9]+]], ![[CON_LAM_B:[0-9]+]]}
+// CHECK: ![[CAP_B]] = !DIDerivedType(tag: DW_TAG_member, name: "x"
+// CHECK-SAME: scope: ![[LAM_B]]
+// CHECK-SAME: line: [[B_LINE]],
+// CHECK-SAME: baseType: ![[INT]]
+// CHECK: ![[CON_LAM_B]] = !DISubprogram(name: "operator()"
+// CHECK-SAME: scope: ![[LAM_B]]
+// CHECK-SAME: line: [[B_LINE]]
+// CHECK-SAME: DIFlagPublic
+
+// C: 17
+// CHECK: ![[C_FUNC:.*]] = distinct !DISubprogram(name: "c"{{.*}}, line: [[C_LINE:[0-9]+]]{{.*}} DISPFlagDefinition
+
+// Back to C. -- 55
+// CHECK: ![[LAM_C:.*]] = distinct !DICompositeType(tag: DW_TAG_class_type{{.*}}, scope: ![[C_FUNC]]{{.*}}, line: [[C_LINE]],
+// CHECK-SAME: elements: ![[LAM_C_ARGS:[0-9]+]]
+// CHECK: ![[LAM_C_ARGS]] = !{![[CAP_C:[0-9]+]], ![[CON_LAM_C:[0-9]+]]}
+// CHECK: ![[CAP_C]] = !DIDerivedType(tag: DW_TAG_member, name: "x"
+// CHECK-SAME: scope: ![[LAM_C]]
+// CHECK-SAME: line: [[C_LINE]],
+// CHECK-SAME: baseType: ![[TYPE_C_x:[0-9]+]]
+// CHECK: ![[TYPE_C_x]] = !DIDerivedType(tag: DW_TAG_reference_type, baseType: ![[INT]]
+// CHECK: ![[CON_LAM_C]] = !DISubprogram(name: "operator()"
+// CHECK-SAME: scope: ![[LAM_C]]
+// CHECK-SAME: line: [[C_LINE]]
+// CHECK-SAME: DIFlagPublic
+
+// D: 18
+// CHECK: ![[D_FUNC:.*]] = distinct !DISubprogram(name: "d"{{.*}}, line: [[D_LINE:[0-9]+]]{{.*}} DISPFlagDefinition
+
+// Back to D. -- 24
+// CHECK: ![[LAM_D:.*]] = distinct !DICompositeType(tag: DW_TAG_class_type{{.*}}, scope: ![[D_FUNC]]{{.*}}, line: [[D_LINE]],
+// CHECK-SAME: elements: ![[LAM_D_ARGS:[0-9]+]]
+// CHECK: ![[LAM_D_ARGS]] = !{![[CAP_D_X:[0-9]+]], ![[CAP_D_Y:[0-9]+]], ![[CON_LAM_D:[0-9]+]]}
+// CHECK: ![[CAP_D_X]] = !DIDerivedType(tag: DW_TAG_member, name: "x"
+// CHECK-SAME: scope: ![[LAM_D]]
+// CHECK-SAME: line: [[D_LINE]],
+// CHECK: ![[CAP_D_Y]] = !DIDerivedType(tag: DW_TAG_member, name: "y"
+// CHECK-SAME: scope: ![[LAM_D]]
+// CHECK-SAME: line: [[D_LINE]],
+// CHECK: ![[CON_LAM_D]] = !DISubprogram(name: "operator()"
+// CHECK-SAME: scope: ![[LAM_D]]
+// CHECK-SAME: line: [[D_LINE]]
+// CHECK-SAME: DIFlagPublic
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-lambda-this.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-lambda-this.cpp
new file mode 100644
index 0000000..eecbac6
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-lambda-this.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -emit-llvm -o - %s -fexceptions -std=c++11 -debug-info-kind=limited | FileCheck %s
+
+struct D {
+ D();
+ D(const D&);
+ int x;
+ int d(int x);
+};
+int D::d(int x) {
+ [=] {
+ return this->x;
+ }();
+}
+
+// CHECK: ![[D:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "D",
+// CHECK: ![[POINTER:.*]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[D]], size: 64)
+// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "this",
+// CHECK-SAME: line: 11
+// CHECK-SAME: baseType: ![[POINTER]]
+// CHECK-SAME: size: 64
+// CHECK-NOT: offset: 0
+// CHECK-SAME: ){{$}}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/debug-prefix-map-lambda.cpp b/src/llvm-project/clang/test/CodeGenCXX/debug-prefix-map-lambda.cpp
new file mode 100644
index 0000000..f0fb1a3
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/debug-prefix-map-lambda.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -debug-info-kind=limited -triple %itanium_abi_triple \
+// RUN: -fdebug-prefix-map=%S=/SOURCE_ROOT %s -emit-llvm -o - | FileCheck %s
+
+template <typename T> void b(T) {}
+void c() {
+ // CHECK: !DISubprogram(name: "b<(lambda at
+ // CHECK-SAME: SOURCE_ROOT
+ // CHECK-SAME: [[@LINE+1]]:{{[0-9]+}})>"
+ b([]{});
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/decl-ref-init.cpp b/src/llvm-project/clang/test/CodeGenCXX/decl-ref-init.cpp
new file mode 100644
index 0000000..117d277
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/decl-ref-init.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm %s -o - | \
+// RUN: FileCheck %s
+// RUN: %clang_cc1 -triple i386-apple-darwin -emit-llvm %s -o - | \
+// RUN: FileCheck %s
+
+struct A {};
+
+struct B
+{
+ operator A&();
+};
+
+
+struct D : public B {
+ operator A();
+};
+
+extern B f();
+extern D d();
+
+int main() {
+ const A& rca = f();
+ const A& rca2 = d();
+}
+
+// CHECK: call dereferenceable({{[0-9]+}}) %struct.A* @_ZN1BcvR1AEv
+// CHECK: call dereferenceable({{[0-9]+}}) %struct.A* @_ZN1BcvR1AEv
diff --git a/src/llvm-project/clang/test/CodeGenCXX/default-arg-temps.cpp b/src/llvm-project/clang/test/CodeGenCXX/default-arg-temps.cpp
new file mode 100644
index 0000000..f7b4681
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/default-arg-temps.cpp
@@ -0,0 +1,80 @@
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s
+
+struct T {
+ T();
+ ~T();
+};
+
+void f(const T& t = T());
+
+class X { // ...
+public:
+ X();
+ X(const X&, const T& t = T());
+};
+
+// CHECK-LABEL: define void @_Z1gv()
+void g() {
+ // CHECK: call void @_ZN1TC1Ev([[T:%.*]]* [[AGG1:%.*]])
+ // CHECK-NEXT: call void @_Z1fRK1T([[T]]* dereferenceable({{[0-9]+}}) [[AGG1]])
+ // CHECK-NEXT: call void @_ZN1TD1Ev([[T]]* [[AGG1]])
+ f();
+
+ // CHECK-NEXT: call void @_ZN1TC1Ev([[T:%.*]]* [[AGG2:%.*]])
+ // CHECK-NEXT: call void @_Z1fRK1T([[T]]* dereferenceable({{[0-9]+}}) [[AGG2]])
+ // CHECK-NEXT: call void @_ZN1TD1Ev([[T]]* [[AGG2]])
+ f();
+
+ // CHECK-NEXT: call void @_ZN1XC1Ev(
+ X a;
+
+ // CHECK-NEXT: call void @_ZN1TC1Ev(
+ // CHECK-NEXT: call void @_ZN1XC1ERKS_RK1T(
+ // CHECK-NEXT: call void @_ZN1TD1Ev(
+ X b(a);
+
+ // CHECK-NEXT: call void @_ZN1TC1Ev(
+ // CHECK-NEXT: call void @_ZN1XC1ERKS_RK1T(
+ // CHECK-NEXT: call void @_ZN1TD1Ev(
+ X c = a;
+}
+
+
+class obj{ int a; float b; double d; };
+// CHECK-LABEL: define void @_Z1hv()
+void h() {
+ // CHECK: call void @llvm.memset.p0i8.i64(
+ obj o = obj();
+}
+
+// PR7028 - mostly this shouldn't crash
+namespace test1 {
+ struct A { A(); };
+ struct B { B(); ~B(); };
+
+ struct C {
+ C(const B &file = B());
+ };
+ C::C(const B &file) {}
+
+ struct D {
+ C c;
+ A a;
+
+ // CHECK-LABEL: 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(
+ // CHECK: call void @_ZN5test11AC1Ev(
+ D() : c(), a() {}
+ };
+
+ D d;
+}
+
+namespace test2 {
+ // CHECK: define linkonce_odr void @_ZN5test21AIiED2Ev(
+ template <typename T> struct A { A() {} ~A() {} };
+ template <typename> void f(const A<int> & = {}) {}
+ void g() { f<int>(); }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/default-arguments.cpp b/src/llvm-project/clang/test/CodeGenCXX/default-arguments.cpp
new file mode 100644
index 0000000..d364835
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/default-arguments.cpp
@@ -0,0 +1,76 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+// PR5484
+namespace PR5484 {
+struct A { };
+extern A a;
+
+void f(const A & = a);
+
+void g() {
+ f();
+}
+}
+
+struct A1 {
+ A1();
+ ~A1();
+};
+
+struct A2 {
+ A2();
+ ~A2();
+};
+
+struct B {
+ B(const A1& = A1(), const A2& = A2());
+};
+
+// CHECK-LABEL: define void @_Z2f1v()
+void f1() {
+
+ // CHECK: call void @_ZN2A1C1Ev(
+ // CHECK: call void @_ZN2A2C1Ev(
+ // CHECK: call void @_ZN1BC1ERK2A1RK2A2(
+ // CHECK: call void @_ZN2A2D1Ev
+ // CHECK: call void @_ZN2A1D1Ev
+ B bs[2];
+}
+
+struct C {
+ B bs[2];
+ C();
+};
+
+// CHECK-LABEL: define void @_ZN1CC2Ev(%struct.C* %this) unnamed_addr
+// CHECK: call void @_ZN2A1C1Ev(
+// CHECK: call void @_ZN2A2C1Ev(
+// CHECK: call void @_ZN1BC1ERK2A1RK2A2(
+// CHECK: call void @_ZN2A2D1Ev
+// CHECK: call void @_ZN2A1D1Ev
+
+// CHECK-LABEL: define void @_ZN1CC1Ev(%struct.C* %this) unnamed_addr
+// CHECK: call void @_ZN1CC2Ev(
+C::C() { }
+
+// CHECK-LABEL: define void @_Z2f3v()
+void f3() {
+ // CHECK: call void @_ZN2A1C1Ev(
+ // CHECK: call void @_ZN2A2C1Ev(
+ // CHECK: call void @_ZN1BC1ERK2A1RK2A2(
+ // CHECK: call void @_ZN2A2D1Ev
+ // CHECK: call void @_ZN2A1D1Ev
+ B *bs = new B[2];
+ delete bs;
+}
+
+void f4() {
+ void g4(int a, int b = 7);
+ {
+ void g4(int a, int b = 5);
+ }
+ void g4(int a = 5, int b);
+
+ // CHECK: call void @_Z2g4ii(i32 5, i32 7)
+ g4();
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/default-constructor-default-argument.cpp b/src/llvm-project/clang/test/CodeGenCXX/default-constructor-default-argument.cpp
new file mode 100644
index 0000000..17ecc35
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/default-constructor-default-argument.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 %s -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %s
+
+// Check that call to constructor for struct A is generated correctly.
+struct A { A(int x = 2); };
+struct B : public A {};
+B x;
+
+// CHECK: call {{.*}} @_ZN1AC2Ei
diff --git a/src/llvm-project/clang/test/CodeGenCXX/default-constructor-for-members.cpp b/src/llvm-project/clang/test/CodeGenCXX/default-constructor-for-members.cpp
new file mode 100644
index 0000000..5eb8cd1
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/default-constructor-for-members.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm %s -o - | \
+// RUN: FileCheck %s
+// RUN: %clang_cc1 -triple i386-apple-darwin -emit-llvm %s -o - | \
+// RUN: FileCheck %s
+
+extern "C" int printf(...);
+
+struct S {
+ S() { printf("S::S()\n"); }
+ int iS;
+};
+
+struct M {
+ S ARR_S;
+};
+
+int main() {
+ M m1;
+}
+
+// CHECK: call void @_ZN1SC1Ev
diff --git a/src/llvm-project/clang/test/CodeGenCXX/default-constructor-template-member.cpp b/src/llvm-project/clang/test/CodeGenCXX/default-constructor-template-member.cpp
new file mode 100644
index 0000000..93df818
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/default-constructor-template-member.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s
+
+template <class T> struct A { A(); };
+struct B { A<int> x; };
+void a() {
+ B b;
+}
+
+// CHECK: call {{.*}} @_ZN1BC1Ev
+// CHECK: define linkonce_odr {{.*}} @_ZN1BC1Ev(%struct.B* {{.*}}%this) unnamed_addr
+// CHECK: call {{.*}} @_ZN1AIiEC1Ev
diff --git a/src/llvm-project/clang/test/CodeGenCXX/default-destructor-nested.cpp b/src/llvm-project/clang/test/CodeGenCXX/default-destructor-nested.cpp
new file mode 100644
index 0000000..77b06d6
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/default-destructor-nested.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 %s -triple %itanium_abi_triple -emit-llvm-only
+// PR6294
+
+class A {
+public: virtual ~A();
+};
+class B {
+ class C;
+};
+class B::C : public A {
+ C();
+};
+B::C::C() {}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/default_calling_conv.cpp b/src/llvm-project/clang/test/CodeGenCXX/default_calling_conv.cpp
new file mode 100644
index 0000000..b5b0f47
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/default_calling_conv.cpp
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -triple i386-unknown-linux-gnu -fdefault-calling-conv=cdecl -emit-llvm -o - %s | FileCheck %s --check-prefix=CDECL --check-prefix=ALL
+// RUN: %clang_cc1 -triple i786-unknown-linux-gnu -target-feature +sse4.2 -fdefault-calling-conv=fastcall -emit-llvm -o - %s | FileCheck %s --check-prefix=FASTCALL --check-prefix=ALL
+// RUN: %clang_cc1 -triple i486-unknown-linux-gnu -fdefault-calling-conv=stdcall -emit-llvm -o - %s | FileCheck %s --check-prefix=STDCALL --check-prefix=ALL
+// RUN: %clang_cc1 -triple i486-unknown-linux-gnu -mrtd -emit-llvm -o - %s | FileCheck %s --check-prefix=STDCALL --check-prefix=ALL
+// RUN: %clang_cc1 -triple i986-unknown-linux-gnu -fdefault-calling-conv=vectorcall -emit-llvm -o - %s | FileCheck %s --check-prefix=VECTORCALL --check-prefix=ALL
+// RUN: %clang_cc1 -triple i986-unknown-linux-gnu -fdefault-calling-conv=regcall -emit-llvm -o - %s | FileCheck %s --check-prefix=REGCALL --check-prefix=ALL
+
+// CDECL: define void @_Z5test1v
+// FASTCALL: define x86_fastcallcc void @_Z5test1v
+// STDCALL: define x86_stdcallcc void @_Z5test1v
+// VECTORCALL: define x86_vectorcallcc void @_Z5test1v
+// REGCALL: define x86_regcallcc void @_Z17__regcall3__test1v
+void test1() {}
+
+// fastcall, stdcall, vectorcall and regcall do not support variadic functions.
+// CDECL: define void @_Z12testVariadicz
+// FASTCALL: define void @_Z12testVariadicz
+// STDCALL: define void @_Z12testVariadicz
+// VECTORCALL: define void @_Z12testVariadicz
+// REGCALL: define void @_Z12testVariadicz
+void testVariadic(...){}
+
+// ALL: define void @_Z5test2v
+void __attribute__((cdecl)) test2() {}
+
+// ALL: define x86_fastcallcc void @_Z5test3v
+void __attribute__((fastcall)) test3() {}
+
+// ALL: define x86_stdcallcc void @_Z5test4v
+void __attribute__((stdcall)) test4() {}
+
+// ALL: define x86_vectorcallcc void @_Z5test5v
+void __attribute__((vectorcall)) test5() {}
+
+// ALL: define x86_regcallcc void @_Z17__regcall3__test6v
+void __attribute__((regcall)) test6() {}
+
+// ALL: define linkonce_odr void @_ZN1A11test_memberEv
+class A {
+public:
+ void test_member() {}
+};
+
+void test() {
+ A a;
+ a.test_member();
+}
+
+// ALL: define i32 @main
+int main() {
+ return 1;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/deferred-global-init.cpp b/src/llvm-project/clang/test/CodeGenCXX/deferred-global-init.cpp
new file mode 100644
index 0000000..e4c0d07
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/deferred-global-init.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 %s -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %s
+// PR5967
+
+extern void* foo;
+static void* const a = foo;
+void* bar() { return a; }
+
+// CHECK: @_ZL1a = internal global i8* null
+
+// CHECK-LABEL: define internal {{.*}}void @__cxx_global_var_init
+// CHECK: load i8*, i8** @foo
+// CHECK: ret void
+
+// CHECK-LABEL: define internal {{.*}}void @_GLOBAL__sub_I_deferred_global_init.cpp
+// CHECK: call {{.*}}void @__cxx_global_var_init()
+// CHECK: ret void
diff --git a/src/llvm-project/clang/test/CodeGenCXX/delayed-template-parsing.cpp b/src/llvm-project/clang/test/CodeGenCXX/delayed-template-parsing.cpp
new file mode 100644
index 0000000..c0e9425
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/delayed-template-parsing.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -fms-extensions -fdelayed-template-parsing -triple=i386-pc-win32 | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -fms-extensions -fdelayed-template-parsing -triple=x86_64-pc-win32 | FileCheck -check-prefix X64 %s
+
+namespace ClassScopeSpecialization {
+ struct Type {
+ template <int i>
+ void Foo() {}
+ template <>
+ void Foo<0>() {}
+ };
+
+ void call() {
+ Type T;
+// CHECK: call {{.*}} @"??$Foo@$0A@@Type@ClassScopeSpecialization@@QAEXXZ"
+// X64: call {{.*}} @"??$Foo@$0A@@Type@ClassScopeSpecialization@@QEAAXXZ"
+ T.Foo<0>();
+ }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/delete-two-arg.cpp b/src/llvm-project/clang/test/CodeGenCXX/delete-two-arg.cpp
new file mode 100644
index 0000000..68a6fa6
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/delete-two-arg.cpp
@@ -0,0 +1,71 @@
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu %s -o - -emit-llvm -verify | FileCheck %s
+// expected-no-diagnostics
+
+typedef __typeof(sizeof(int)) size_t;
+
+namespace test1 {
+ struct A { void operator delete(void*,size_t); int x; };
+
+ // CHECK-LABEL: 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 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, i8* [[NEW]], i32 4
+ // CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to [[A]]*
+ // CHECK-NEXT: ret [[A]]* [[T2]]
+ return ::new A[10];
+ }
+
+ // CHECK-LABEL: 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]]*, [[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, i8* [[T2]], i32 -4
+ // CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to i32*
+ // CHECK-NEXT: [[T5:%.*]] = load i32, 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-LABEL: define void @_ZN5test34testEv()
+ void test() {
+ // CHECK: call i8* @_Znaj(i32 24)
+ // CHECK-NEXT: bitcast
+ // CHECK-NEXT: store i32 5
+ (void) new B[5];
+ }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/delete.cpp b/src/llvm-project/clang/test/CodeGenCXX/delete.cpp
new file mode 100644
index 0000000..ff448f8
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/delete.cpp
@@ -0,0 +1,148 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -emit-llvm -o - | FileCheck %s
+
+void t1(int *a) {
+ delete a;
+}
+
+struct S {
+ int a;
+};
+
+// POD types.
+void t3(S *s) {
+ delete s;
+}
+
+// Non-POD
+struct T {
+ ~T();
+ int a;
+};
+
+// CHECK-LABEL: define void @_Z2t4P1T
+void t4(T *t) {
+ // CHECK: call void @_ZN1TD1Ev
+ // CHECK-NEXT: bitcast
+ // CHECK-NEXT: call void @_ZdlPv
+ delete t;
+}
+
+// PR5102
+template <typename T>
+class A {
+ public: operator T *() const;
+};
+
+void f() {
+ A<char*> a;
+
+ delete a;
+}
+
+namespace test0 {
+ struct A {
+ void *operator new(__SIZE_TYPE__ sz);
+ void operator delete(void *p) { ::operator delete(p); }
+ ~A() {}
+ };
+
+ // CHECK-LABEL: define void @_ZN5test04testEPNS_1AE(
+ void test(A *a) {
+ // CHECK: call void @_ZN5test01AD1Ev
+ // CHECK-NEXT: bitcast
+ // CHECK-NEXT: call void @_ZN5test01AdlEPv
+ delete a;
+ }
+
+ // CHECK-LABEL: define linkonce_odr void @_ZN5test01AD1Ev(%"struct.test0::A"* %this) unnamed_addr
+ // CHECK-LABEL: define linkonce_odr void @_ZN5test01AdlEPv
+}
+
+namespace test1 {
+ struct A {
+ int x;
+ ~A();
+ };
+
+ // CHECK-LABEL: define void @_ZN5test14testEPA10_A20_NS_1AE(
+ void test(A (*arr)[10][20]) {
+ delete [] arr;
+ // CHECK: icmp eq [10 x [20 x [[A:%.*]]]]* [[PTR:%.*]], null
+ // CHECK-NEXT: br i1
+
+ // CHECK: [[BEGIN:%.*]] = getelementptr inbounds [10 x [20 x [[A]]]], [10 x [20 x [[A]]]]* [[PTR]], i32 0, i32 0, i32 0
+ // CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[BEGIN]] to i8*
+ // CHECK-NEXT: [[ALLOC:%.*]] = getelementptr inbounds i8, i8* [[T0]], i64 -8
+ // CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[ALLOC]] to i64*
+ // CHECK-NEXT: [[COUNT:%.*]] = load i64, i64* [[T1]]
+ // CHECK: [[END:%.*]] = getelementptr inbounds [[A]], [[A]]* [[BEGIN]], i64 [[COUNT]]
+ // CHECK-NEXT: [[ISEMPTY:%.*]] = icmp eq [[A]]* [[BEGIN]], [[END]]
+ // CHECK-NEXT: br i1 [[ISEMPTY]],
+ // CHECK: [[PAST:%.*]] = phi [[A]]* [ [[END]], {{%.*}} ], [ [[CUR:%.*]], {{%.*}} ]
+ // CHECK-NEXT: [[CUR:%.*]] = getelementptr inbounds [[A]], [[A]]* [[PAST]], i64 -1
+ // CHECK-NEXT: call void @_ZN5test11AD1Ev([[A]]* [[CUR]])
+ // CHECK-NEXT: [[ISDONE:%.*]] = icmp eq [[A]]* [[CUR]], [[BEGIN]]
+ // CHECK-NEXT: br i1 [[ISDONE]]
+ // CHECK: call void @_ZdaPv(i8* [[ALLOC]])
+ }
+}
+
+namespace test2 {
+ // CHECK-LABEL: define void @_ZN5test21fEPb
+ void f(bool *b) {
+ // CHECK: call void @_ZdlPv(i8*
+ delete b;
+ // CHECK: call void @_ZdaPv(i8*
+ delete [] b;
+ }
+}
+
+namespace test3 {
+ void f(int a[10][20]) {
+ // CHECK: call void @_ZdaPv(i8*
+ delete a;
+ }
+}
+
+namespace test4 {
+ // PR10341: ::delete with a virtual destructor
+ struct X {
+ virtual ~X();
+ void operator delete (void *);
+ };
+
+ // CHECK-LABEL: define void @_ZN5test421global_delete_virtualEPNS_1XE
+ void global_delete_virtual(X *xp) {
+ // Load the offset-to-top from the vtable and apply it.
+ // This has to be done first because the dtor can mess it up.
+ // CHECK: [[T0:%.*]] = bitcast [[X:%.*]]* [[XP:%.*]] to i64**
+ // CHECK-NEXT: [[VTABLE:%.*]] = load i64*, i64** [[T0]]
+ // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds i64, i64* [[VTABLE]], i64 -2
+ // CHECK-NEXT: [[OFFSET:%.*]] = load i64, i64* [[T0]], align 8
+ // CHECK-NEXT: [[T0:%.*]] = bitcast [[X]]* [[XP]] to i8*
+ // CHECK-NEXT: [[ALLOCATED:%.*]] = getelementptr inbounds i8, i8* [[T0]], i64 [[OFFSET]]
+ // Load the complete-object destructor (not the deleting destructor)
+ // and call it.
+ // CHECK-NEXT: [[T0:%.*]] = bitcast [[X:%.*]]* [[XP:%.*]] to void ([[X]]*)***
+ // CHECK-NEXT: [[VTABLE:%.*]] = load void ([[X]]*)**, void ([[X]]*)*** [[T0]]
+ // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds void ([[X]]*)*, void ([[X]]*)** [[VTABLE]], i64 0
+ // CHECK-NEXT: [[DTOR:%.*]] = load void ([[X]]*)*, void ([[X]]*)** [[T0]]
+ // CHECK-NEXT: call void [[DTOR]]([[X]]* [[OBJ:%.*]])
+ // Call the global operator delete.
+ // CHECK-NEXT: call void @_ZdlPv(i8* [[ALLOCATED]]) [[NUW:#[0-9]+]]
+ ::delete xp;
+ }
+}
+
+namespace test5 {
+ struct Incomplete;
+ // CHECK-LABEL: define void @_ZN5test523array_delete_incompleteEPNS_10IncompleteES1_
+ void array_delete_incomplete(Incomplete *p1, Incomplete *p2) {
+ // CHECK: call void @_ZdlPv
+ delete p1;
+ // CHECK: call void @_ZdaPv
+ delete [] p2;
+ }
+}
+
+// CHECK: attributes [[NUW]] = {{[{].*}} nounwind {{.*[}]}}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/dependent-type-member-pointer.cpp b/src/llvm-project/clang/test/CodeGenCXX/dependent-type-member-pointer.cpp
new file mode 100644
index 0000000..595eca5
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/dependent-type-member-pointer.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -emit-llvm-only -verify %s
+// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc -emit-llvm-only -verify %s
+// expected-no-diagnostics
+// PR7736
+
+template <class scriptmemberptr> int InitMember(scriptmemberptr);
+
+template <class>
+struct contentmap
+{
+ static void InitDataMap()
+ { InitMember(&contentmap::SizeHolder); }
+ int SizeHolder;
+};
+
+void ReadFrom( )
+{
+ contentmap<int>::InitDataMap();
+}
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/derived-cast.cpp b/src/llvm-project/clang/test/CodeGenCXX/derived-cast.cpp
new file mode 100644
index 0000000..bf2b258
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/derived-cast.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck %s
+
+class A {
+ int a;
+};
+
+class B {
+ int b;
+public:
+ A *getAsA();
+};
+
+class X : public A, public B {
+ int x;
+};
+
+// PR35909 - https://bugs.llvm.org/show_bug.cgi?id=35909
+
+A *B::getAsA() {
+ return static_cast<X*>(this);
+
+ // CHECK-LABEL: define %class.A* @_ZN1B6getAsAEv
+ // CHECK: %[[THIS:.*]] = load %class.B*, %class.B**
+ // CHECK-NEXT: %[[BC:.*]] = bitcast %class.B* %[[THIS]] to i8*
+ // CHECK-NEXT: getelementptr inbounds i8, i8* %[[BC]], i64 -4
+}
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/derived-to-base-conv.cpp b/src/llvm-project/clang/test/CodeGenCXX/derived-to-base-conv.cpp
new file mode 100644
index 0000000..402fa44
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/derived-to-base-conv.cpp
@@ -0,0 +1,86 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm %s -o - | FileCheck %s
+
+struct A {
+ A(const A&);
+ A();
+ ~A();
+};
+
+struct B : public A {
+ B();
+ B(const B& Other);
+ ~B();
+};
+
+struct C : public B {
+ C();
+ C(const C& Other);
+ ~C();
+};
+
+struct X {
+ operator B&();
+ operator C&();
+ X(const X&);
+ X();
+ ~X();
+ B b;
+ C c;
+};
+
+void test0_helper(A);
+void test0(X x) {
+ test0_helper(x);
+ // CHECK-LABEL: define void @_Z5test01X(
+ // CHECK: [[TMP:%.*]] = alloca [[A:%.*]], align
+ // CHECK-NEXT: [[T0:%.*]] = call dereferenceable({{[0-9]+}}) [[B:%.*]]* @_ZN1XcvR1BEv(
+ // CHECK-NEXT: [[T1:%.*]] = bitcast [[B]]* [[T0]] to [[A]]*
+ // CHECK-NEXT: call void @_ZN1AC1ERKS_([[A]]* [[TMP]], [[A]]* dereferenceable({{[0-9]+}}) [[T1]])
+ // CHECK-NEXT: call void @_Z12test0_helper1A([[A]]* [[TMP]])
+ // CHECK-NEXT: call void @_ZN1AD1Ev([[A]]* [[TMP]])
+ // CHECK-NEXT: ret void
+}
+
+struct Base;
+
+struct Root {
+ operator Base&();
+};
+
+struct Derived;
+
+struct Base : Root {
+ Base(const Base &);
+ Base();
+ operator Derived &();
+};
+
+struct Derived : Base {
+};
+
+void test1_helper(Base);
+void test1(Derived bb) {
+ // CHECK-LABEL: define void @_Z5test17Derived(
+ // CHECK-NOT: call {{.*}} @_ZN4BasecvR7DerivedEv(
+ // CHECK: call void @_ZN4BaseC1ERKS_(
+ // CHECK-NOT: call {{.*}} @_ZN4BasecvR7DerivedEv(
+ // CHECK: call void @_Z12test1_helper4Base(
+ test1_helper(bb);
+}
+
+// Don't crash after devirtualizing a derived-to-base conversion
+// to an empty base allocated at offset zero.
+// rdar://problem/11993704
+class Test2a {};
+class Test2b final : public virtual Test2a {};
+void test2(Test2b &x) {
+ Test2a &y = x;
+ // CHECK-LABEL: define void @_Z5test2R6Test2b(
+ // CHECK: [[X:%.*]] = alloca [[B:%.*]]*, align 8
+ // CHECK-NEXT: [[Y:%.*]] = alloca [[A:%.*]]*, align 8
+ // CHECK-NEXT: store [[B]]* {{%.*}}, [[B]]** [[X]], align 8
+ // CHECK-NEXT: [[T0:%.*]] = load [[B]]*, [[B]]** [[X]], align 8
+ // CHECK-NEXT: [[T1:%.*]] = bitcast [[B]]* [[T0]] to [[A]]*
+ // CHECK-NEXT: store [[A]]* [[T1]], [[A]]** [[Y]], align 8
+ // CHECK-NEXT: ret void
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/derived-to-base.cpp b/src/llvm-project/clang/test/CodeGenCXX/derived-to-base.cpp
new file mode 100644
index 0000000..3bd5e35
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/derived-to-base.cpp
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+struct A {
+ void f();
+
+ int a;
+};
+
+struct B : A {
+ double b;
+};
+
+void f() {
+ B b;
+
+ b.f();
+}
+
+// CHECK: define %struct.B* @_Z1fP1A(%struct.A* %a) [[NUW:#[0-9]+]]
+B *f(A *a) {
+ // CHECK-NOT: br label
+ // CHECK: ret %struct.B*
+ return static_cast<B*>(a);
+}
+
+// PR5965
+namespace PR5965 {
+
+// CHECK: define %struct.A* @_ZN6PR59651fEP1B(%struct.B* %b) [[NUW]]
+A *f(B* b) {
+ // CHECK-NOT: br label
+ // CHECK: ret %struct.A*
+ return 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());
+ }
+}
+
+// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/derived-to-virtual-base-class-calls-final.cpp b/src/llvm-project/clang/test/CodeGenCXX/derived-to-virtual-base-class-calls-final.cpp
new file mode 100644
index 0000000..3a4766d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/derived-to-virtual-base-class-calls-final.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 %s -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %s
+
+struct A { int i; };
+struct B { char j; };
+struct C : A, B { int k; };
+
+struct D final : virtual C {
+ D();
+ virtual void f();
+};
+
+// CHECK-LABEL: define {{.*}}dereferenceable({{[0-9]+}}) %struct.B* @_Z1fR1D
+B &f(D &d) {
+ // CHECK-NOT: load i8*, i8**
+ return d;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/destructor-calls.cpp b/src/llvm-project/clang/test/CodeGenCXX/destructor-calls.cpp
new file mode 100644
index 0000000..4da46a4
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/destructor-calls.cpp
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 %s -emit-llvm -o %t
+
+extern "C" int printf(...);
+
+static int val;
+
+struct B {
+ B() : iB(++val) { printf("B()\n"); }
+ int iB;
+ ~B() { printf("~B(%d)\n", iB); --val; }
+};
+
+struct M : B {
+ M() : iM(++val) { printf("M()\n"); }
+ int iM;
+ ~M() { printf("~M(%d)\n", iM); --val; }
+};
+
+struct P {
+ P() : iP(++val) { printf("P()\n"); }
+ int iP;
+ ~P() { printf("~P(%d)\n", iP); --val; }
+};
+
+struct N : M, P {
+ N() { printf("N()\n"); iN = ++val; }
+ ~N() { printf("~N(%d) val = %d\n", iN, --val); }
+ int iN;
+ M m;
+ P p;
+};
+
+struct O : B {
+ ~O() { return; }
+};
+
+int main() {
+ N n1;
+ N n2;
+ O o;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/destructor-crash.cpp b/src/llvm-project/clang/test/CodeGenCXX/destructor-crash.cpp
new file mode 100644
index 0000000..4329198
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/destructor-crash.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 %s -emit-llvm -std=c++11 -o %t
+
+struct A {
+ ~A();
+};
+
+struct B {
+ A a;
+};
+
+struct C {
+ union {
+ B b;
+ };
+
+ ~C() noexcept;
+};
+
+C::~C() noexcept {}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/destructor-debug-info.cpp b/src/llvm-project/clang/test/CodeGenCXX/destructor-debug-info.cpp
new file mode 100644
index 0000000..7b10f83
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/destructor-debug-info.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -debug-info-kind=limited -S -emit-llvm %s -o - | FileCheck %s
+
+class A { int a; };
+class B {
+public:
+ B() { a = new A; }
+ ~B() { delete a; }
+private:
+ A *a;
+};
+
+void fn(B b);
+
+int i;
+void foo() {
+ if (i) {
+ B b1;
+ fn (b1);
+ }
+}
+// Check there is a line number entry for line 19 where b1 is destructed.
+// CHECK: !DILocation(line: 19,
diff --git a/src/llvm-project/clang/test/CodeGenCXX/destructor-exception-spec.cpp b/src/llvm-project/clang/test/CodeGenCXX/destructor-exception-spec.cpp
new file mode 100644
index 0000000..50c17ef
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/destructor-exception-spec.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm-only %s -std=c++11
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm-only -fno-use-cxa-atexit %s -std=c++11
+// RUN: %clang_cc1 -triple %ms_abi_triple -fno-rtti -emit-llvm-only %s -std=c++11
+
+// PR13479: don't crash with -fno-exceptions.
+namespace {
+ struct SchedulePostRATDList {
+ virtual ~SchedulePostRATDList();
+ };
+
+ SchedulePostRATDList::~SchedulePostRATDList() {}
+
+ SchedulePostRATDList Scheduler;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/destructors.cpp b/src/llvm-project/clang/test/CodeGenCXX/destructors.cpp
new file mode 100644
index 0000000..ba8333b0
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/destructors.cpp
@@ -0,0 +1,532 @@
+// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o - -mconstructor-aliases -fcxx-exceptions -fexceptions -O1 -disable-llvm-passes -std=c++03 > %t
+// RUN: FileCheck --check-prefix=CHECK1 --input-file=%t %s
+// RUN: FileCheck --check-prefix=CHECK2 --input-file=%t %s
+// RUN: FileCheck --check-prefix=CHECK3 --input-file=%t %s
+// RUN: FileCheck --check-prefixes=CHECK4,CHECK4v03 --input-file=%t %s
+// RUN: FileCheck --check-prefixes=CHECK5,CHECK5v03 --input-file=%t %s
+// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o - -mconstructor-aliases -fcxx-exceptions -fexceptions -O1 -disable-llvm-passes -std=c++11 > %t2
+// RUN: FileCheck --check-prefix=CHECK1 --input-file=%t2 %s
+// RUN: FileCheck --check-prefix=CHECK2v11 --input-file=%t2 %s
+// RUN: FileCheck --check-prefix=CHECK3 --input-file=%t2 %s
+// RUN: FileCheck --check-prefixes=CHECK4,CHECK4v11 --input-file=%t2 %s
+// RUN: FileCheck --check-prefixes=CHECK5,CHECK5v11 --input-file=%t2 %s
+// RUN: FileCheck --check-prefix=CHECK6 --input-file=%t2 %s
+// REQUIRES: asserts
+
+struct A {
+ int a;
+
+ ~A();
+};
+
+// Base with non-trivial destructor
+struct B : A {
+ ~B();
+};
+
+B::~B() { }
+
+// Field with non-trivial destructor
+struct C {
+ A a;
+
+ ~C();
+};
+
+C::~C() { }
+
+namespace PR7526 {
+ extern void foo();
+ struct allocator {
+ ~allocator() throw();
+ };
+
+ struct allocator_derived : allocator { };
+
+ // CHECK1-LABEL: define void @_ZN6PR75263fooEv()
+ // CHECK1: call void {{.*}} @_ZN6PR75269allocatorD2Ev
+
+ // CHECK1-LABEL: define void @_ZN6PR75269allocatorD2Ev(%"struct.PR7526::allocator"* %this) unnamed_addr
+ // CHECK1: call void @__cxa_call_unexpected
+ allocator::~allocator() throw() { foo(); }
+
+ void foo() {
+ allocator_derived ad;
+ }
+}
+
+// PR5084
+template<typename T>
+class A1 {
+ ~A1();
+};
+
+template<> A1<char>::~A1();
+
+// PR5529
+namespace PR5529 {
+ struct A {
+ ~A();
+ };
+
+ A::~A() { }
+ struct B : A {
+ virtual ~B();
+ };
+
+ B::~B() {}
+}
+
+// FIXME: there's a known problem in the codegen here where, if one
+// destructor throws, the remaining destructors aren't run. Fix it,
+// then make this code check for it.
+namespace test0 {
+ void foo();
+ struct VBase { ~VBase(); };
+ struct Base { ~Base(); };
+ struct Member { ~Member(); };
+
+ struct A : Base {
+ Member M;
+ ~A();
+ };
+
+ // The function-try-block won't suppress -mconstructor-aliases here.
+ A::~A() try { } catch (int i) {}
+
+// complete destructor alias tested above
+
+// CHECK2-LABEL: @_ZN5test01AD1Ev = unnamed_addr alias {{.*}} @_ZN5test01AD2Ev
+// CHECK2-LABEL: define void @_ZN5test01AD2Ev(%"struct.test0::A"* %this) unnamed_addr
+// CHECK2: invoke void @_ZN5test06MemberD1Ev
+// CHECK2: unwind label [[MEM_UNWIND:%[a-zA-Z0-9.]+]]
+// CHECK2: invoke void @_ZN5test04BaseD2Ev
+// CHECK2: unwind label [[BASE_UNWIND:%[a-zA-Z0-9.]+]]
+
+// In C++11, the destructors are often known not to throw.
+// CHECK2v11-LABEL: @_ZN5test01AD1Ev = unnamed_addr alias {{.*}} @_ZN5test01AD2Ev
+// CHECK2v11-LABEL: define void @_ZN5test01AD2Ev(%"struct.test0::A"* %this) unnamed_addr
+// CHECK2v11: call void @_ZN5test06MemberD1Ev
+// CHECK2v11: call void @_ZN5test04BaseD2Ev
+
+ struct B : Base, virtual VBase {
+ Member M;
+ ~B();
+ };
+ B::~B() try { } catch (int i) {}
+ // It will suppress the delegation optimization here, though.
+
+// CHECK2-LABEL: define void @_ZN5test01BD2Ev(%"struct.test0::B"* %this, i8** %vtt) unnamed_addr
+// CHECK2: invoke void @_ZN5test06MemberD1Ev
+// CHECK2: unwind label [[MEM_UNWIND:%[a-zA-Z0-9.]+]]
+// CHECK2: invoke void @_ZN5test04BaseD2Ev
+// CHECK2: unwind label [[BASE_UNWIND:%[a-zA-Z0-9.]+]]
+
+// CHECK2v11-LABEL: define void @_ZN5test01BD2Ev(%"struct.test0::B"* %this, i8** %vtt) unnamed_addr
+// CHECK2v11: call void @_ZN5test06MemberD1Ev
+// CHECK2v11: call void @_ZN5test04BaseD2Ev
+
+// CHECK2-LABEL: define void @_ZN5test01BD1Ev(%"struct.test0::B"* %this) unnamed_addr
+// CHECK2: invoke void @_ZN5test06MemberD1Ev
+// CHECK2: unwind label [[MEM_UNWIND:%[a-zA-Z0-9.]+]]
+// CHECK2: invoke void @_ZN5test04BaseD2Ev
+// CHECK2: unwind label [[BASE_UNWIND:%[a-zA-Z0-9.]+]]
+// CHECK2: invoke void @_ZN5test05VBaseD2Ev
+// CHECK2: unwind label [[VBASE_UNWIND:%[a-zA-Z0-9.]+]]
+
+// CHECK2v11-LABEL: define void @_ZN5test01BD1Ev(%"struct.test0::B"* %this) unnamed_addr
+// CHECK2v11: call void @_ZN5test06MemberD1Ev
+// CHECK2v11: call void @_ZN5test04BaseD2Ev
+// CHECK2v11: call void @_ZN5test05VBaseD2Ev
+}
+
+// Test base-class aliasing.
+namespace test1 {
+ struct A { ~A(); char ***m; }; // non-trivial destructor
+ struct B { ~B(); }; // non-trivial destructor
+ struct Empty { }; // trivial destructor, empty
+ struct NonEmpty { int x; }; // trivial destructor, non-empty
+
+ // There must be a definition in this translation unit for the alias
+ // optimization to apply.
+ A::~A() { delete m; }
+
+ struct M : A { ~M(); };
+ M::~M() {}
+ // CHECK3: @_ZN5test11MD2Ev = unnamed_addr alias {{.*}} @_ZN5test11AD2Ev
+
+ struct N : A, Empty { ~N(); };
+ N::~N() {}
+ // CHECK3: @_ZN5test11ND2Ev = unnamed_addr alias {{.*}} @_ZN5test11AD2Ev
+
+ struct O : Empty, A { ~O(); };
+ O::~O() {}
+ // CHECK3: @_ZN5test11OD2Ev = unnamed_addr alias {{.*}} @_ZN5test11AD2Ev
+
+ struct P : NonEmpty, A { ~P(); };
+ P::~P() {} // CHECK3-LABEL: define void @_ZN5test11PD2Ev(%"struct.test1::P"* %this) unnamed_addr
+
+ struct Q : A, B { ~Q(); };
+ Q::~Q() {} // CHECK3-LABEL: define void @_ZN5test11QD2Ev(%"struct.test1::Q"* %this) unnamed_addr
+
+ struct R : A { ~R(); };
+ R::~R() { A a; } // CHECK3-LABEL: define void @_ZN5test11RD2Ev(%"struct.test1::R"* %this) unnamed_addr
+
+ struct S : A { ~S(); int x; };
+ S::~S() {}
+ // CHECK4: @_ZN5test11SD2Ev = unnamed_addr alias {{.*}}, bitcast {{.*}} @_ZN5test11AD2Ev
+
+ struct T : A { ~T(); B x; };
+ T::~T() {} // CHECK4-LABEL: 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() {} // CHECK4-LABEL: define void @_ZN5test11UD2Ev(%"struct.test1::U"* %this, i8** %vtt) unnamed_addr
+}
+
+// PR6471
+namespace test2 {
+ struct A { ~A(); char ***m; };
+ struct B : A { ~B(); };
+
+ B::~B() {}
+ // CHECK4-LABEL: define void @_ZN5test21BD2Ev(%"struct.test2::B"* %this) unnamed_addr
+ // CHECK4: call void @_ZN5test21AD2Ev
+}
+
+// PR7142
+namespace test3 {
+ struct A { virtual ~A(); };
+ struct B { virtual ~B(); };
+ namespace { // internal linkage => deferred
+ struct C : A, B {}; // ~B() in D requires a this-adjustment thunk
+ struct D : C {}; // D::~D() is an alias to C::~C()
+ }
+
+ void test() {
+ new D; // Force emission of D's vtable
+ }
+
+ // CHECK4-LABEL: define internal void @_ZN5test312_GLOBAL__N_11CD2Ev(%"struct.test3::(anonymous namespace)::C"* %this) unnamed_addr
+ // CHECK4v03: invoke void @_ZN5test31BD2Ev(
+ // CHECK4v11: call void @_ZN5test31BD2Ev(
+ // CHECK4: call void @_ZN5test31AD2Ev(
+ // CHECK4: ret void
+
+ // CHECK4-LABEL: define internal void @_ZN5test312_GLOBAL__N_11DD0Ev(%"struct.test3::(anonymous namespace)::D"* %this) unnamed_addr
+ // CHECK4v03-SAME: personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ // CHECK4v03: invoke void {{.*}} @_ZN5test312_GLOBAL__N_11CD2Ev
+ // CHECK4v11: call void {{.*}} @_ZN5test312_GLOBAL__N_11CD2Ev
+ // CHECK4: call void @_ZdlPv({{.*}}) [[NUW:#[0-9]+]]
+ // CHECK4: ret void
+ // CHECK4v03: landingpad { i8*, i32 }
+ // CHECK4v03-NEXT: cleanup
+ // CHECK4v03: call void @_ZdlPv({{.*}}) [[NUW]]
+ // CHECK4v03: resume { i8*, i32 }
+ // CHECK4v11-NOT: landingpad
+
+ // CHECK4-LABEL: define internal void @_ZThn8_N5test312_GLOBAL__N_11DD1Ev(
+ // CHECK4: getelementptr inbounds i8, i8* {{.*}}, i64 -8
+ // CHECK4: call void {{.*}} @_ZN5test312_GLOBAL__N_11CD2Ev
+ // CHECK4: ret void
+
+ // CHECK4-LABEL: define internal void @_ZThn8_N5test312_GLOBAL__N_11DD0Ev(
+ // CHECK4: getelementptr inbounds i8, i8* {{.*}}, i64 -8
+ // CHECK4: call void @_ZN5test312_GLOBAL__N_11DD0Ev(
+ // CHECK4: ret void
+
+ // CHECK4-LABEL: define internal void @_ZN5test312_GLOBAL__N_11CD0Ev(%"struct.test3::(anonymous namespace)::C"* %this) unnamed_addr
+ // CHECK4v03-SAME: personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ // CHECK4v03: invoke void @_ZN5test312_GLOBAL__N_11CD2Ev(
+ // CHECK4v11: call void @_ZN5test312_GLOBAL__N_11CD2Ev(
+ // CHECK4: call void @_ZdlPv({{.*}}) [[NUW]]
+ // CHECK4: ret void
+ // CHECK4v03: landingpad { i8*, i32 }
+ // CHECK4v03-NEXT: cleanup
+ // CHECK4v03: call void @_ZdlPv({{.*}}) [[NUW]]
+ // CHECK4v03: resume { i8*, i32 }
+
+ // CHECK4-LABEL: define internal void @_ZThn8_N5test312_GLOBAL__N_11CD1Ev(
+ // CHECK4: getelementptr inbounds i8, i8* {{.*}}, i64 -8
+ // CHECK4: call void @_ZN5test312_GLOBAL__N_11CD2Ev(
+ // CHECK4: ret void
+
+ // CHECK4-LABEL: define internal void @_ZThn8_N5test312_GLOBAL__N_11CD0Ev(
+ // CHECK4: getelementptr inbounds i8, i8* {{.*}}, i64 -8
+ // CHECK4: call void @_ZN5test312_GLOBAL__N_11CD0Ev(
+ // CHECK4: ret void
+
+ // CHECK4-LABEL: declare void @_ZN5test31BD2Ev(
+ // CHECK4-LABEL: declare void @_ZN5test31AD2Ev(
+
+ // CHECK4: attributes [[NUW]] = {{[{].*}} nounwind {{.*[}]}}
+}
+
+namespace test4 {
+ struct A { ~A(); };
+
+ // CHECK5-LABEL: define void @_ZN5test43fooEv()
+ // CHECK5: call void @_ZN5test41AD1Ev
+ // CHECK5: ret void
+ void foo() {
+ {
+ A a;
+ goto failure;
+ }
+
+ failure:
+ return;
+ }
+
+ // CHECK5-LABEL: define void @_ZN5test43barEi(
+ // CHECK5: [[X:%.*]] = alloca i32
+ // CHECK5-NEXT: [[A:%.*]] = alloca
+ // CHECK5: br label
+ // CHECK5: [[TMP:%.*]] = load i32, i32* [[X]]
+ // CHECK5-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP]], 0
+ // CHECK5-NEXT: br i1
+ // CHECK5: call void @_ZN5test41AD1Ev(
+ // CHECK5: br label
+ // CHECK5: [[TMP:%.*]] = load i32, i32* [[X]]
+ // CHECK5: [[TMP2:%.*]] = add nsw i32 [[TMP]], -1
+ // CHECK5: store i32 [[TMP2]], i32* [[X]]
+ // CHECK5: br label
+ // CHECK5: ret void
+ void bar(int x) {
+ for (A a; x; ) {
+ x--;
+ }
+ }
+}
+
+// PR7575
+namespace test5 {
+ struct A { ~A(); };
+
+ // CHECK5-LABEL: define void @_ZN5test53fooEv()
+ // CHECK5: [[ELEMS:%.*]] = alloca [5 x [[A:%.*]]], align
+ // CHECK5v03-NEXT: [[EXN:%.*]] = alloca i8*
+ // CHECK5v03-NEXT: [[SEL:%.*]] = alloca i32
+ // CHECK5-NEXT: [[PELEMS:%.*]] = bitcast [5 x [[A]]]* [[ELEMS]] to i8*
+ // CHECK5-NEXT: call void @llvm.lifetime.start.p0i8(i64 5, i8* [[PELEMS]])
+ // CHECK5-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [5 x [[A]]], [5 x [[A]]]* [[ELEMS]], i32 0, i32 0
+ // CHECK5-NEXT: [[END:%.*]] = getelementptr inbounds [[A]], [[A]]* [[BEGIN]], i64 5
+ // CHECK5-NEXT: br label
+ // CHECK5: [[POST:%.*]] = phi [[A]]* [ [[END]], {{%.*}} ], [ [[ELT:%.*]], {{%.*}} ]
+ // CHECK5-NEXT: [[ELT]] = getelementptr inbounds [[A]], [[A]]* [[POST]], i64 -1
+ // CHECK5v03-NEXT: invoke void @_ZN5test51AD1Ev([[A]]* [[ELT]])
+ // CHECK5v11-NEXT: call void @_ZN5test51AD1Ev([[A]]* [[ELT]])
+ // CHECK5: [[T0:%.*]] = icmp eq [[A]]* [[ELT]], [[BEGIN]]
+ // CHECK5-NEXT: br i1 [[T0]],
+ // CHECK5: call void @llvm.lifetime.end
+ // CHECK5-NEXT: ret void
+ // lpad
+ // CHECK5v03: [[EMPTY:%.*]] = icmp eq [[A]]* [[BEGIN]], [[ELT]]
+ // CHECK5v03-NEXT: br i1 [[EMPTY]]
+ // CHECK5v03: [[AFTER:%.*]] = phi [[A]]* [ [[ELT]], {{%.*}} ], [ [[CUR:%.*]], {{%.*}} ]
+ // CHECK5v03-NEXT: [[CUR:%.*]] = getelementptr inbounds [[A]], [[A]]* [[AFTER]], i64 -1
+ // CHECK5v03-NEXT: invoke void @_ZN5test51AD1Ev([[A]]* [[CUR]])
+ // CHECK5v03: [[DONE:%.*]] = icmp eq [[A]]* [[CUR]], [[BEGIN]]
+ // CHECK5v03-NEXT: br i1 [[DONE]],
+ // CHECK5v11-NOT: landingpad
+ // CHECK5v11: }
+ void foo() {
+ A elems[5];
+ }
+}
+
+namespace test6 {
+ void opaque();
+
+ struct A { ~A(); };
+ template <unsigned> struct B { B(); ~B(); int _; };
+ struct C : B<0>, B<1>, virtual B<2>, virtual B<3> {
+ A x, y, z;
+
+ C();
+ ~C();
+ };
+
+ C::C() { opaque(); }
+ // CHECK5-LABEL: define void @_ZN5test61CC1Ev(%"struct.test6::C"* %this) unnamed_addr
+ // CHECK5: call void @_ZN5test61BILj2EEC2Ev
+ // CHECK5: invoke void @_ZN5test61BILj3EEC2Ev
+ // CHECK5: invoke void @_ZN5test61BILj0EEC2Ev
+ // CHECK5: invoke void @_ZN5test61BILj1EEC2Ev
+ // CHECK5: invoke void @_ZN5test66opaqueEv
+ // CHECK5: ret void
+ // FIXME: way too much EH cleanup code follows
+
+ C::~C() { opaque(); }
+ // CHECK5-LABEL: define void @_ZN5test61CD2Ev(%"struct.test6::C"* %this, i8** %vtt) unnamed_addr
+ // CHECK5: invoke void @_ZN5test66opaqueEv
+ // CHECK5v03: invoke void @_ZN5test61AD1Ev
+ // CHECK5v03: invoke void @_ZN5test61AD1Ev
+ // CHECK5v03: invoke void @_ZN5test61AD1Ev
+ // CHECK5v03: invoke void @_ZN5test61BILj1EED2Ev
+ // CHECK5v11: call void @_ZN5test61AD1Ev
+ // CHECK5v11: call void @_ZN5test61AD1Ev
+ // CHECK5v11: call void @_ZN5test61AD1Ev
+ // CHECK5v11: call void @_ZN5test61BILj1EED2Ev
+ // CHECK5: call void @_ZN5test61BILj0EED2Ev
+ // CHECK5: ret void
+ // CHECK5v03: invoke void @_ZN5test61AD1Ev
+ // CHECK5v03: invoke void @_ZN5test61AD1Ev
+ // CHECK5v03: invoke void @_ZN5test61AD1Ev
+ // CHECK5v03: invoke void @_ZN5test61BILj1EED2Ev
+ // CHECK5v03: invoke void @_ZN5test61BILj0EED2Ev
+
+ // CHECK5-LABEL: define void @_ZN5test61CD1Ev(%"struct.test6::C"* %this) unnamed_addr
+ // CHECK5v03: invoke void @_ZN5test61CD2Ev
+ // CHECK5v03: invoke void @_ZN5test61BILj3EED2Ev
+ // CHECK5v03: call void @_ZN5test61BILj2EED2Ev
+ // CHECK5v03: ret void
+ // CHECK5v03: invoke void @_ZN5test61BILj3EED2Ev
+ // CHECK5v03: invoke void @_ZN5test61BILj2EED2Ev
+
+ // CHECK5v11: call void @_ZN5test61CD2Ev
+ // CHECK5v11: call void @_ZN5test61BILj3EED2Ev
+ // CHECK5v11: call void @_ZN5test61BILj2EED2Ev
+ // CHECK5v11: ret void
+}
+
+// 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
+ // CHECK5-LABEL: define void @_ZN5test71BD2Ev(
+ // CHECK5v03: invoke void @_ZN5test71DD1Ev(
+ // CHECK5v11: call void @_ZN5test71DD1Ev(
+ // CHECK5: call void @_ZN5test71AD2Ev(
+ B::~B() {}
+}
+
+// PR10467
+namespace test8 {
+ struct A { A(); ~A(); };
+
+ void die() __attribute__((noreturn));
+ void test() {
+ A x;
+ while (1) {
+ A y;
+ goto l;
+ }
+ l: die();
+ }
+
+ // CHECK5-LABEL: define void @_ZN5test84testEv()
+ // CHECK5: [[X:%.*]] = alloca [[A:%.*]], align 1
+ // CHECK5-NEXT: [[Y:%.*]] = alloca [[A:%.*]], align 1
+ // CHECK5: call void @_ZN5test81AC1Ev([[A]]* [[X]])
+ // CHECK5-NEXT: br label
+ // CHECK5: invoke void @_ZN5test81AC1Ev([[A]]* [[Y]])
+ // CHECK5v03: invoke void @_ZN5test81AD1Ev([[A]]* [[Y]])
+ // CHECK5v11: call void @_ZN5test81AD1Ev([[A]]* [[Y]])
+ // CHECK5-NOT: switch
+ // CHECK5: invoke void @_ZN5test83dieEv()
+ // CHECK5: unreachable
+}
+
+// PR12710
+namespace test9 {
+ struct ArgType {
+ ~ArgType();
+ };
+ template<typename T>
+ void f1(const ArgType& = ArgType());
+ void f2();
+ void bar() {
+ f1<int>();
+ f2();
+ }
+ // CHECK5: call void @_ZN5test97ArgTypeD1Ev(%"struct.test9::ArgType"* %
+ // CHECK5: call void @_ZN5test92f2Ev()
+}
+
+namespace test10 {
+ // We used to crash trying to replace _ZN6test106OptionD1Ev with
+ // _ZN6test106OptionD2Ev twice.
+ struct Option {
+ virtual ~Option() {}
+ };
+ template <class DataType> class opt : public Option {};
+ template class opt<int>;
+ // CHECK5-LABEL: define zeroext i1 @_ZN6test1016handleOccurrenceEv(
+ bool handleOccurrence() {
+ // CHECK5: call void @_ZN6test106OptionD2Ev(
+ Option x;
+ return true;
+ }
+}
+
+#if __cplusplus >= 201103L
+namespace test11 {
+
+// Check that lifetime.end is emitted in the landing pad.
+
+// CHECK6-LABEL: define void @_ZN6test1115testLifetimeEndEi(
+// CHECK6: entry:
+// CHECK6: [[T1:%[a-z0-9]+]] = alloca %"struct.test11::S1"
+// CHECK6: [[T2:%[a-z0-9]+]] = alloca %"struct.test11::S1"
+// CHECK6: [[T3:%[a-z0-9]+]] = alloca %"struct.test11::S1"
+
+// CHECK6: {{^}}invoke.cont
+// CHECK6: call void @_ZN6test112S1D1Ev(%"struct.test11::S1"* [[T1]])
+// CHECK6: [[BC1:%[a-z0-9]+]] = bitcast %"struct.test11::S1"* [[T1]] to i8*
+// CHECK6: call void @llvm.lifetime.end.p0i8(i64 32, i8* [[BC1]])
+// CHECK6: {{^}}lpad
+// CHECK6: call void @_ZN6test112S1D1Ev(%"struct.test11::S1"* [[T1]])
+// CHECK6: [[BC2:%[a-z0-9]+]] = bitcast %"struct.test11::S1"* [[T1]] to i8*
+// CHECK6: call void @llvm.lifetime.end.p0i8(i64 32, i8* [[BC2]])
+
+// CHECK6: {{^}}invoke.cont
+// CHECK6: call void @_ZN6test112S1D1Ev(%"struct.test11::S1"* [[T2]])
+// CHECK6: [[BC3:%[a-z0-9]+]] = bitcast %"struct.test11::S1"* [[T2]] to i8*
+// CHECK6: call void @llvm.lifetime.end.p0i8(i64 32, i8* [[BC3]])
+// CHECK6: {{^}}lpad
+// CHECK6: call void @_ZN6test112S1D1Ev(%"struct.test11::S1"* [[T2]])
+// CHECK6: [[BC4:%[a-z0-9]+]] = bitcast %"struct.test11::S1"* [[T2]] to i8*
+// CHECK6: call void @llvm.lifetime.end.p0i8(i64 32, i8* [[BC4]])
+
+// CHECK6: {{^}}invoke.cont
+// CHECK6: call void @_ZN6test112S1D1Ev(%"struct.test11::S1"* [[T3]])
+// CHECK6: [[BC5:%[a-z0-9]+]] = bitcast %"struct.test11::S1"* [[T3]] to i8*
+// CHECK6: call void @llvm.lifetime.end.p0i8(i64 32, i8* [[BC5]])
+// CHECK6: {{^}}lpad
+// CHECK6: call void @_ZN6test112S1D1Ev(%"struct.test11::S1"* [[T3]])
+// CHECK6: [[BC6:%[a-z0-9]+]] = bitcast %"struct.test11::S1"* [[T3]] to i8*
+// CHECK6: call void @llvm.lifetime.end.p0i8(i64 32, i8* [[BC6]])
+
+ struct S1 {
+ ~S1();
+ int a[8];
+ };
+
+ void func1(S1 &) noexcept(false);
+
+ void testLifetimeEnd(int n) {
+ if (n < 10) {
+ S1 t1;
+ func1(t1);
+ } else if (n < 100) {
+ S1 t2;
+ func1(t2);
+ } else if (n < 1000) {
+ S1 t3;
+ func1(t3);
+ }
+ }
+
+}
+#endif
diff --git a/src/llvm-project/clang/test/CodeGenCXX/devirtualize-ms-dtor.cpp b/src/llvm-project/clang/test/CodeGenCXX/devirtualize-ms-dtor.cpp
new file mode 100644
index 0000000..d999b0c
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/devirtualize-ms-dtor.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows-msvc %s -emit-llvm -o - | FileCheck %s
+
+// If we de-virtualize ~Foo, we still need to call ??1Foo, not ??_DFoo.
+
+struct Base {
+ virtual ~Base();
+};
+struct Foo final : Base {
+};
+void f(Foo *p) {
+ p->~Foo();
+}
+
+// CHECK-LABEL: define{{.*}} void @"?f@@YAXPEAUFoo@@@Z"(%struct.Foo* %p)
+// CHECK: call void @"??1Foo@@UEAA@XZ"
+// CHECK: ret void
diff --git a/src/llvm-project/clang/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp b/src/llvm-project/clang/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp
new file mode 100644
index 0000000..2ab2f75
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp
@@ -0,0 +1,293 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -std=c++11 %s -emit-llvm -o - | FileCheck %s
+
+namespace Test1 {
+ struct A {
+ virtual int f() final;
+ };
+
+ // CHECK-LABEL: define i32 @_ZN5Test11fEPNS_1AE
+ int f(A *a) {
+ // CHECK: call i32 @_ZN5Test11A1fEv
+ return a->f();
+ }
+}
+
+namespace Test2 {
+ struct A final {
+ virtual int f();
+ };
+
+ // CHECK-LABEL: 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-LABEL: define i32 @_ZN5Test31fEPNS_1BE
+ int f(B *b) {
+ // CHECK: call i32 @_ZN5Test31A1fEv
+ return b->f();
+ }
+
+ // CHECK-LABEL: define i32 @_ZN5Test31fERNS_1BE
+ int f(B &b) {
+ // CHECK: call i32 @_ZN5Test31A1fEv
+ return b.f();
+ }
+
+ // CHECK-LABEL: define i32 @_ZN5Test31fEPv
+ int f(void *v) {
+ // CHECK: call i32 @_ZN5Test31A1fEv
+ return static_cast<B*>(v)->f();
+ }
+}
+
+namespace Test4 {
+ struct A {
+ virtual void f();
+ virtual int operator-();
+ };
+
+ struct B final : A {
+ virtual void f();
+ virtual int operator-();
+ };
+
+ // CHECK-LABEL: define void @_ZN5Test41fEPNS_1BE
+ void f(B* d) {
+ // CHECK: call void @_ZN5Test41B1fEv
+ static_cast<A*>(d)->f();
+ // CHECK: call i32 @_ZN5Test41BngEv
+ -static_cast<A&>(*d);
+ }
+}
+
+namespace Test5 {
+ struct A {
+ virtual void f();
+ virtual int operator-();
+ };
+
+ struct B : A {
+ virtual void f();
+ virtual int operator-();
+ };
+
+ struct C final : B {
+ };
+
+ // CHECK-LABEL: define void @_ZN5Test51fEPNS_1CE
+ void f(C* d) {
+ // FIXME: It should be possible to devirtualize this case, but that is
+ // not implemented yet.
+ // CHECK: getelementptr
+ // CHECK-NEXT: %[[FUNC:.*]] = load
+ // CHECK-NEXT: call void %[[FUNC]]
+ static_cast<A*>(d)->f();
+ }
+ // CHECK-LABEL: define void @_ZN5Test53fopEPNS_1CE
+ void fop(C* d) {
+ // FIXME: It should be possible to devirtualize this case, but that is
+ // not implemented yet.
+ // CHECK: getelementptr
+ // CHECK-NEXT: %[[FUNC:.*]] = load
+ // CHECK-NEXT: call i32 %[[FUNC]]
+ -static_cast<A&>(*d);
+ }
+}
+
+namespace Test6 {
+ struct A {
+ virtual ~A();
+ };
+
+ struct B : public A {
+ virtual ~B();
+ };
+
+ struct C {
+ virtual ~C();
+ };
+
+ struct D final : public C, public B {
+ };
+
+ // CHECK-LABEL: define void @_ZN5Test61fEPNS_1DE
+ void f(D* d) {
+ // CHECK: call void @_ZN5Test61DD1Ev
+ static_cast<A*>(d)->~A();
+ }
+}
+
+namespace Test7 {
+ struct foo {
+ virtual void g() {}
+ };
+
+ struct bar {
+ virtual int f() { return 0; }
+ };
+
+ struct zed final : public foo, public bar {
+ int z;
+ virtual int f() {return z;}
+ };
+
+ // CHECK-LABEL: define i32 @_ZN5Test71fEPNS_3zedE
+ int f(zed *z) {
+ // CHECK: alloca
+ // CHECK-NEXT: store
+ // CHECK-NEXT: load
+ // CHECK-NEXT: call i32 @_ZN5Test73zed1fEv
+ // CHECK-NEXT: ret
+ return static_cast<bar*>(z)->f();
+ }
+}
+
+namespace Test8 {
+ struct A { virtual ~A() {} };
+ struct B {
+ int b;
+ virtual int foo() { return b; }
+ };
+ struct C final : A, B { };
+ // CHECK-LABEL: define i32 @_ZN5Test84testEPNS_1CE
+ int test(C *c) {
+ // CHECK: %[[THIS:.*]] = phi
+ // CHECK-NEXT: call i32 @_ZN5Test81B3fooEv(%"struct.Test8::B"* %[[THIS]])
+ return static_cast<B*>(c)->foo();
+ }
+}
+
+namespace Test9 {
+ struct A {
+ int a;
+ };
+ struct B {
+ int b;
+ };
+ struct C : public B, public A {
+ };
+ struct RA {
+ virtual A *f() {
+ return 0;
+ }
+ virtual A *operator-() {
+ return 0;
+ }
+ };
+ struct RC final : public RA {
+ virtual C *f() {
+ C *x = new C();
+ x->a = 1;
+ x->b = 2;
+ return x;
+ }
+ virtual C *operator-() {
+ C *x = new C();
+ x->a = 1;
+ x->b = 2;
+ return x;
+ }
+ };
+ // CHECK: define {{.*}} @_ZN5Test91fEPNS_2RCE
+ A *f(RC *x) {
+ // FIXME: It should be possible to devirtualize this case, but that is
+ // not implemented yet.
+ // CHECK: load
+ // CHECK: bitcast
+ // CHECK: [[F_PTR_RA:%.+]] = bitcast
+ // CHECK: [[VTABLE:%.+]] = load {{.+}} [[F_PTR_RA]]
+ // CHECK: [[VFN:%.+]] = getelementptr inbounds {{.+}} [[VTABLE]], i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[FUNC:.*]] = load {{.+}} [[VFN]]
+ // CHECK-NEXT: = call {{.*}} %[[FUNC]]
+ return static_cast<RA*>(x)->f();
+ }
+ // CHECK: define {{.*}} @_ZN5Test93fopEPNS_2RCE
+ A *fop(RC *x) {
+ // FIXME: It should be possible to devirtualize this case, but that is
+ // not implemented yet.
+ // CHECK: load
+ // CHECK: bitcast
+ // CHECK: [[F_PTR_RA:%.+]] = bitcast
+ // CHECK: [[VTABLE:%.+]] = load {{.+}} [[F_PTR_RA]]
+ // CHECK: [[VFN:%.+]] = getelementptr inbounds {{.+}} [[VTABLE]], i{{[0-9]+}} 1
+ // CHECK-NEXT: %[[FUNC:.*]] = load {{.+}} [[VFN]]
+ // CHECK-NEXT: = call {{.*}} %[[FUNC]]
+ return -static_cast<RA&>(*x);
+ }
+}
+
+namespace Test10 {
+ struct A {
+ virtual int f();
+ };
+
+ struct B : A {
+ int f() final;
+ };
+
+ // CHECK-LABEL: define i32 @_ZN6Test101fEPNS_1BE
+ int f(B *b) {
+ // CHECK: call i32 @_ZN6Test101B1fEv
+ return static_cast<A *>(b)->f();
+ }
+}
+
+namespace Test11 {
+ // Check that the definitions of Derived's operators are emitted.
+
+ // CHECK-LABEL: define linkonce_odr void @_ZN6Test111SIiE4foo1Ev(
+ // CHECK: call void @_ZN6Test111SIiE7DerivedclEv(
+ // CHECK: call zeroext i1 @_ZN6Test111SIiE7DerivedeqERKNS_4BaseE(
+ // CHECK: call zeroext i1 @_ZN6Test111SIiE7DerivedntEv(
+ // CHECK: call dereferenceable(4) %"class.Test11::Base"* @_ZN6Test111SIiE7DerivedixEi(
+ // CHECK: define linkonce_odr void @_ZN6Test111SIiE7DerivedclEv(
+ // CHECK: define linkonce_odr zeroext i1 @_ZN6Test111SIiE7DerivedeqERKNS_4BaseE(
+ // CHECK: define linkonce_odr zeroext i1 @_ZN6Test111SIiE7DerivedntEv(
+ // CHECK: define linkonce_odr dereferenceable(4) %"class.Test11::Base"* @_ZN6Test111SIiE7DerivedixEi(
+ class Base {
+ public:
+ virtual void operator()() {}
+ virtual bool operator==(const Base &other) { return false; }
+ virtual bool operator!() { return false; }
+ virtual Base &operator[](int i) { return *this; }
+ };
+
+ template<class T>
+ struct S {
+ class Derived final : public Base {
+ public:
+ void operator()() override {}
+ bool operator==(const Base &other) override { return true; }
+ bool operator!() override { return true; }
+ Base &operator[](int i) override { return *this; }
+ };
+
+ Derived *ptr = nullptr, *ptr2 = nullptr;
+
+ void foo1() {
+ if (ptr && ptr2) {
+ // These calls get devirtualized. Linkage fails if the definitions of
+ // the called functions are not emitted.
+ (*ptr)();
+ (void)(*ptr == *ptr2);
+ (void)(!(*ptr));
+ (void)((*ptr)[1]);
+ }
+ }
+ };
+
+ void foo2() {
+ S<int> *s = new S<int>;
+ s->foo1();
+ }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp b/src/llvm-project/clang/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp
new file mode 100644
index 0000000..b4c39f3
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp
@@ -0,0 +1,197 @@
+// RUN: %clang_cc1 -std=c++98 %s -triple armv7-none-eabi -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 %s -triple armv7-none-eabi -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++1z %s -triple armv7-none-eabi -emit-llvm -o - | FileCheck %s
+
+struct A {
+ virtual void f();
+ virtual void f_const() const;
+ virtual void g();
+
+ A h();
+};
+
+A g();
+
+void f(A a, A *ap, A& ar) {
+ // This should not be a virtual function call.
+
+ // CHECK: call void @_ZN1A1fEv(%struct.A* %a)
+ a.f();
+
+ // CHECK: call void %
+ ap->f();
+
+ // CHECK: call void %
+ ar.f();
+
+ // CHECK: call void @_ZN1A1fEv
+ A().f();
+
+ // CHECK: call void @_ZN1A1fEv
+ g().f();
+
+ // CHECK: call void @_ZN1A1fEv
+ a.h().f();
+
+ // CHECK: call void @_ZNK1A7f_constEv
+ a.f_const();
+
+ // CHECK: call void @_ZN1A1fEv
+ (a).f();
+}
+
+struct D : A { virtual void g(); };
+struct XD { D d; };
+
+D gd();
+
+void fd(D d, XD xd, D *p) {
+ // CHECK: call void @_ZN1A1fEv(%struct.A*
+ d.f();
+
+ // CHECK: call void @_ZN1D1gEv(%struct.D*
+ d.g();
+
+ // CHECK: call void @_ZN1A1fEv
+ D().f();
+
+ // CHECK: call void @_ZN1D1gEv
+ D().g();
+
+ // CHECK: call void @_ZN1A1fEv
+ gd().f();
+
+ // CHECK: call void @_ZNK1A7f_constEv
+ d.f_const();
+
+ // CHECK: call void @_ZN1A1fEv
+ (d).f();
+
+ // CHECK: call void @_ZN1A1fEv
+ (true, d).f();
+
+ // CHECK: call void @_ZN1D1gEv
+ (true, d).g();
+
+ // CHECK: call void @_ZN1A1fEv
+ xd.d.f();
+
+ // CHECK: call void @_ZN1A1fEv
+ XD().d.f();
+
+ // CHECK: call void @_ZN1A1fEv
+ D XD::*mp;
+ (xd.*mp).f();
+
+ // CHECK: call void @_ZN1D1gEv
+ (xd.*mp).g();
+
+ // Can't devirtualize this; we have no guarantee that p points to a D here,
+ // due to the "single object is considered to be an array of one element"
+ // rule.
+ // CHECK: call void %
+ p[0].f();
+
+ // FIXME: We can devirtualize this, by C++1z [expr.add]/6 (if the array
+ // element type and the pointee type are not similar, behavior is undefined).
+ // CHECK: call void %
+ p[1].f();
+}
+
+struct B {
+ virtual void f();
+ ~B();
+
+ B h();
+};
+
+
+void f() {
+ // CHECK: call void @_ZN1B1fEv
+ B().f();
+
+ // CHECK: call void @_ZN1B1fEv
+ B().h().f();
+}
+
+namespace test2 {
+ struct foo {
+ virtual void f();
+ virtual ~foo();
+ };
+
+ struct bar : public foo {
+ virtual void f();
+ virtual ~bar();
+ };
+
+ void f(bar *b) {
+ // CHECK: call void @_ZN5test23foo1fEv
+ // CHECK: call %"struct.test2::foo"* @_ZN5test23fooD1Ev
+ b->foo::f();
+ b->foo::~foo();
+ }
+}
+
+namespace test3 {
+ // Test that we don't crash in this case.
+ struct B {
+ };
+ struct D : public B {
+ };
+ void f(D d) {
+ // CHECK-LABEL: define void @_ZN5test31fENS_1DE
+ d.B::~B();
+ }
+}
+
+namespace test4 {
+ struct Animal {
+ virtual void eat();
+ };
+ struct Fish : Animal {
+ virtual void eat();
+ };
+ struct Wrapper {
+ Fish fish;
+ };
+ extern Wrapper *p;
+ void test() {
+ // CHECK: call void @_ZN5test44Fish3eatEv
+ p->fish.eat();
+ }
+}
+
+// Do not devirtualize to pure virtual function calls.
+namespace test5 {
+ struct X {
+ virtual void f() = 0;
+ };
+ struct Y {};
+ // CHECK-LABEL: define {{.*}} @_ZN5test51f
+ void f(Y &y, X Y::*p) {
+ // CHECK-NOT: call {{.*}} @_ZN5test51X1fEv
+ // CHECK: call void %
+ (y.*p).f();
+ };
+
+ struct Z final {
+ virtual void f() = 0;
+ };
+ // CHECK-LABEL: define {{.*}} @_ZN5test51g
+ void g(Z &z) {
+ // CHECK-NOT: call {{.*}} @_ZN5test51Z1fEv
+ // CHECK: call void %
+ z.f();
+ }
+
+ struct Q {
+ virtual void f() final = 0;
+ };
+ // CHECK-LABEL: define {{.*}} @_ZN5test51h
+ void h(Q &q) {
+ // CHECK-NOT: call {{.*}} @_ZN5test51Q1fEv
+ // CHECK: call void %
+ q.f();
+ }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/discard-name-values.cpp b/src/llvm-project/clang/test/CodeGenCXX/discard-name-values.cpp
new file mode 100644
index 0000000..d4d7527
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/discard-name-values.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -emit-llvm -triple=armv7-apple-darwin -std=c++11 %s -o - -O1 \
+// RUN: | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -triple=armv7-apple-darwin -std=c++11 %s -o - -O1 \
+// RUN: -discard-value-names | FileCheck %s --check-prefix=DISCARDVALUE
+
+extern "C" void branch();
+
+bool test(bool pred) {
+ // DISCARDVALUE: br i1 %0, label %2, label %3
+ // CHECK: br i1 %pred, label %if.then, label %if.end
+
+ if (pred) {
+ // DISCARDVALUE: ; <label>:2:
+ // DISCARDVALUE-NEXT: tail call void @branch()
+ // DISCARDVALUE-NEXT: br label %3
+
+ // CHECK: if.then:
+ // CHECK-NEXT: tail call void @branch()
+ // CHECK-NEXT: br label %if.end
+ branch();
+ }
+
+ // DISCARDVALUE: ; <label>:3:
+ // DISCARDVALUE-NEXT: ret i1 %0
+
+ // CHECK: if.end:
+ // CHECK-NEXT: ret i1 %pred
+ return pred;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/dllexport-alias.cpp b/src/llvm-project/clang/test/CodeGenCXX/dllexport-alias.cpp
new file mode 100644
index 0000000..7eec9cf
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/dllexport-alias.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -triple x86_64-windows-gnu -mconstructor-aliases %s -S -emit-llvm -o - | FileCheck %s
+
+// This test assumes that the C1 constructor will be aliased to the C2
+// constructor, and the D1 destructor to the D2. It then checks that the aliases
+// are dllexport'ed.
+
+class __declspec(dllexport) A {
+public:
+ A();
+ ~A();
+};
+
+A::A() {}
+
+A::~A() {}
+
+// CHECK: @_ZN1AC1Ev = dso_local dllexport unnamed_addr alias void (%class.A*), void (%class.A*)* @_ZN1AC2Ev
+// CHECK: @_ZN1AD1Ev = dso_local dllexport unnamed_addr alias void (%class.A*), void (%class.A*)* @_ZN1AD2Ev
diff --git a/src/llvm-project/clang/test/CodeGenCXX/dllexport-ctor-closure.cpp b/src/llvm-project/clang/test/CodeGenCXX/dllexport-ctor-closure.cpp
new file mode 100644
index 0000000..72d674d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/dllexport-ctor-closure.cpp
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -triple i686-windows-msvc -emit-llvm -std=c++14 \
+// RUN: -fno-threadsafe-statics -fms-extensions -O1 -mconstructor-aliases \
+// RUN: -disable-llvm-passes -o - %s -w -fms-compatibility-version=19.00 | \
+// RUN: FileCheck %s
+
+struct CtorWithClosure {
+ __declspec(dllexport) CtorWithClosure(...) {}
+// CHECK-LABEL: define weak_odr dso_local dllexport x86_thiscallcc void @"??_FCtorWithClosure@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat
+// CHECK: %[[this_addr:.*]] = alloca %struct.CtorWithClosure*, align 4
+// CHECK: store %struct.CtorWithClosure* %this, %struct.CtorWithClosure** %[[this_addr]], align 4
+// CHECK: %[[this:.*]] = load %struct.CtorWithClosure*, %struct.CtorWithClosure** %[[this_addr]]
+// CHECK: call %struct.CtorWithClosure* (%struct.CtorWithClosure*, ...) @"??0CtorWithClosure@@QAA@ZZ"(%struct.CtorWithClosure* %[[this]])
+// CHECK: ret void
+};
+
+struct CtorWithClosureOutOfLine {
+ __declspec(dllexport) CtorWithClosureOutOfLine(...);
+};
+CtorWithClosureOutOfLine::CtorWithClosureOutOfLine(...) {}
+// CHECK-LABEL: define weak_odr dso_local dllexport x86_thiscallcc void @"??_FCtorWithClosureOutOfLine@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat
+
+#define DELETE_IMPLICIT_MEMBERS(ClassName) \
+ ClassName(ClassName &&) = delete; \
+ ClassName(ClassName &) = delete; \
+ ~ClassName() = delete; \
+ ClassName &operator=(ClassName &) = delete
+
+struct __declspec(dllexport) ClassWithClosure {
+ DELETE_IMPLICIT_MEMBERS(ClassWithClosure);
+ ClassWithClosure(...) {}
+// CHECK-LABEL: define weak_odr dso_local dllexport x86_thiscallcc void @"??_FClassWithClosure@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat
+// CHECK: %[[this_addr:.*]] = alloca %struct.ClassWithClosure*, align 4
+// CHECK: store %struct.ClassWithClosure* %this, %struct.ClassWithClosure** %[[this_addr]], align 4
+// CHECK: %[[this:.*]] = load %struct.ClassWithClosure*, %struct.ClassWithClosure** %[[this_addr]]
+// CHECK: call %struct.ClassWithClosure* (%struct.ClassWithClosure*, ...) @"??0ClassWithClosure@@QAA@ZZ"(%struct.ClassWithClosure* %[[this]])
+// CHECK: ret void
+};
+
+template <typename T> struct TemplateWithClosure {
+ TemplateWithClosure(int x = sizeof(T)) {}
+};
+extern template struct TemplateWithClosure<char>;
+template struct __declspec(dllexport) TemplateWithClosure<char>;
+extern template struct TemplateWithClosure<int>;
+template struct __declspec(dllexport) TemplateWithClosure<int>;
+
+// CHECK-LABEL: define weak_odr dso_local dllexport x86_thiscallcc void @"??_F?$TemplateWithClosure@D@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat
+// CHECK: call {{.*}} @"??0?$TemplateWithClosure@D@@QAE@H@Z"({{.*}}, i32 1)
+
+// CHECK-LABEL: define weak_odr dso_local dllexport x86_thiscallcc void @"??_F?$TemplateWithClosure@H@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat
+// CHECK: call {{.*}} @"??0?$TemplateWithClosure@H@@QAE@H@Z"({{.*}}, i32 4)
+
+struct __declspec(dllexport) NestedOuter {
+ DELETE_IMPLICIT_MEMBERS(NestedOuter);
+ NestedOuter(void *p = 0) {}
+ struct __declspec(dllexport) NestedInner {
+ DELETE_IMPLICIT_MEMBERS(NestedInner);
+ NestedInner(void *p = 0) {}
+ };
+};
+
+// CHECK-LABEL: define weak_odr dso_local dllexport x86_thiscallcc void @"??_FNestedOuter@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat
+// CHECK-LABEL: define weak_odr dso_local dllexport x86_thiscallcc void @"??_FNestedInner@NestedOuter@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat
+
+struct HasDtor {
+ ~HasDtor();
+ int o;
+};
+struct HasImplicitDtor1 { HasDtor o; };
+struct HasImplicitDtor2 { HasDtor o; };
+struct __declspec(dllexport) CtorClosureInline {
+ CtorClosureInline(const HasImplicitDtor1 &v = {}) {}
+};
+struct __declspec(dllexport) CtorClosureOutOfLine {
+ CtorClosureOutOfLine(const HasImplicitDtor2 &v = {});
+};
+CtorClosureOutOfLine::CtorClosureOutOfLine(const HasImplicitDtor2 &v) {}
+
+// CHECK-LABEL: define weak_odr dso_local dllexport x86_thiscallcc void @"??_FCtorClosureInline@@QAEXXZ"
+// CHECK-LABEL: define linkonce_odr dso_local x86_thiscallcc void @"??1HasImplicitDtor1@@QAE@XZ"
+// CHECK-LABEL: define weak_odr dso_local dllexport x86_thiscallcc void @"??_FCtorClosureOutOfLine@@QAEXXZ"
+// CHECK-LABEL: define linkonce_odr dso_local x86_thiscallcc void @"??1HasImplicitDtor2@@QAE@XZ"
diff --git a/src/llvm-project/clang/test/CodeGenCXX/dllexport-dtor-thunks.cpp b/src/llvm-project/clang/test/CodeGenCXX/dllexport-dtor-thunks.cpp
new file mode 100644
index 0000000..bda126e
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/dllexport-dtor-thunks.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -mconstructor-aliases -fms-extensions %s -emit-llvm -o - -triple x86_64-windows-msvc | FileCheck %s
+
+struct __declspec(dllexport) A { virtual ~A(); };
+struct __declspec(dllexport) B { virtual ~B(); };
+struct __declspec(dllexport) C : A, B { virtual ~C(); };
+C::~C() {}
+
+// CHECK: define dso_local dllexport void @"??1C@@UEAA@XZ"
+// This thunk should *not* be dllexport.
+// CHECK: define linkonce_odr dso_local i8* @"??_EC@@W7EAAPEAXI@Z"
diff --git a/src/llvm-project/clang/test/CodeGenCXX/dllexport-members.cpp b/src/llvm-project/clang/test/CodeGenCXX/dllexport-members.cpp
new file mode 100644
index 0000000..b027538
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/dllexport-members.cpp
@@ -0,0 +1,681 @@
+// RUN: %clang_cc1 -triple i686-windows-msvc -fms-compatibility -fms-compatibility-version=18 -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=MSC --check-prefix=M32 %s
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -fms-compatibility -fms-compatibility-version=18 -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=MSC --check-prefix=M64 %s
+// RUN: %clang_cc1 -triple i686-windows-msvc -fms-compatibility -fms-compatibility-version=19 -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=M32VS2015 %s
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -fms-compatibility -fms-compatibility-version=19 -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=M64VS2015 %s
+// RUN: %clang_cc1 -triple i686-windows-gnu -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=GNU --check-prefix=G32 %s
+// RUN: %clang_cc1 -triple x86_64-windows-gnu -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=GNU --check-prefix=G64 %s
+
+// Helper structs to make templates more expressive.
+struct ImplicitInst_Exported {};
+struct ExplicitDecl_Exported {};
+struct ExplicitInst_Exported {};
+struct ExplicitSpec_Exported {};
+struct ExplicitSpec_Def_Exported {};
+struct ExplicitSpec_InlineDef_Exported {};
+struct ExplicitSpec_NotExported {};
+
+extern "C" void* malloc(__SIZE_TYPE__ size);
+extern "C" void free(void* p);
+
+
+//===----------------------------------------------------------------------===//
+// Class members
+//===----------------------------------------------------------------------===//
+
+// Export individual members of a class.
+struct ExportMembers {
+ struct Nested;
+
+ // M32-DAG: define dso_local dllexport x86_thiscallcc void @"?normalDef@ExportMembers@@QAEXXZ"(%struct.ExportMembers* %this)
+ // M64-DAG: define dso_local dllexport void @"?normalDef@ExportMembers@@QEAAXXZ"(%struct.ExportMembers* %this)
+ // M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?normalInclass@ExportMembers@@QAEXXZ"(%struct.ExportMembers* %this)
+ // M64-DAG: define weak_odr dso_local dllexport void @"?normalInclass@ExportMembers@@QEAAXXZ"(%struct.ExportMembers* %this)
+ // M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?normalInlineDef@ExportMembers@@QAEXXZ"(%struct.ExportMembers* %this)
+ // M64-DAG: define weak_odr dso_local dllexport void @"?normalInlineDef@ExportMembers@@QEAAXXZ"(%struct.ExportMembers* %this)
+ // M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?normalInlineDecl@ExportMembers@@QAEXXZ"(%struct.ExportMembers* %this)
+ // M64-DAG: define weak_odr dso_local dllexport void @"?normalInlineDecl@ExportMembers@@QEAAXXZ"(%struct.ExportMembers* %this)
+ // G32-DAG: define dso_local dllexport x86_thiscallcc void @_ZN13ExportMembers9normalDefEv(%struct.ExportMembers* %this)
+ // G64-DAG: define dso_local dllexport void @_ZN13ExportMembers9normalDefEv(%struct.ExportMembers* %this)
+ // G32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @_ZN13ExportMembers13normalInclassEv(%struct.ExportMembers* %this)
+ // G64-DAG: define weak_odr dso_local dllexport void @_ZN13ExportMembers13normalInclassEv(%struct.ExportMembers* %this)
+ // G32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @_ZN13ExportMembers15normalInlineDefEv(%struct.ExportMembers* %this)
+ // G64-DAG: define weak_odr dso_local dllexport void @_ZN13ExportMembers15normalInlineDefEv(%struct.ExportMembers* %this)
+ // G32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @_ZN13ExportMembers16normalInlineDeclEv(%struct.ExportMembers* %this)
+ // G64-DAG: define weak_odr dso_local dllexport void @_ZN13ExportMembers16normalInlineDeclEv(%struct.ExportMembers* %this)
+ // M32-DAG: define linkonce_odr dso_local x86_thiscallcc void @"?referencedNonExportedInClass@ExportMembers@@QAEXXZ"
+ __declspec(dllexport) void normalDef();
+ __declspec(dllexport) void normalInclass() { referencedNonExportedInClass(); }
+ __declspec(dllexport) void normalInlineDef();
+ __declspec(dllexport) inline void normalInlineDecl();
+ void referencedNonExportedInClass() {}
+
+ // M32-DAG: define dso_local dllexport x86_thiscallcc void @"?virtualDef@ExportMembers@@UAEXXZ"(%struct.ExportMembers* %this)
+ // M64-DAG: define dso_local dllexport void @"?virtualDef@ExportMembers@@UEAAXXZ"(%struct.ExportMembers* %this)
+ // M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?virtualInclass@ExportMembers@@UAEXXZ"(%struct.ExportMembers* %this)
+ // M64-DAG: define weak_odr dso_local dllexport void @"?virtualInclass@ExportMembers@@UEAAXXZ"(%struct.ExportMembers* %this)
+ // M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?virtualInlineDef@ExportMembers@@UAEXXZ"(%struct.ExportMembers* %this)
+ // M64-DAG: define weak_odr dso_local dllexport void @"?virtualInlineDef@ExportMembers@@UEAAXXZ"(%struct.ExportMembers* %this)
+ // M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?virtualInlineDecl@ExportMembers@@UAEXXZ"(%struct.ExportMembers* %this)
+ // M64-DAG: define weak_odr dso_local dllexport void @"?virtualInlineDecl@ExportMembers@@UEAAXXZ"(%struct.ExportMembers* %this)
+ // G32-DAG: define dso_local dllexport x86_thiscallcc void @_ZN13ExportMembers10virtualDefEv(%struct.ExportMembers* %this)
+ // G64-DAG: define dso_local dllexport void @_ZN13ExportMembers10virtualDefEv(%struct.ExportMembers* %this)
+ // G32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @_ZN13ExportMembers14virtualInclassEv(%struct.ExportMembers* %this)
+ // G64-DAG: define weak_odr dso_local dllexport void @_ZN13ExportMembers14virtualInclassEv(%struct.ExportMembers* %this)
+ // G32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @_ZN13ExportMembers16virtualInlineDefEv(%struct.ExportMembers* %this)
+ // G64-DAG: define weak_odr dso_local dllexport void @_ZN13ExportMembers16virtualInlineDefEv(%struct.ExportMembers* %this)
+ // G32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @_ZN13ExportMembers17virtualInlineDeclEv(%struct.ExportMembers* %this)
+ // G64-DAG: define weak_odr dso_local dllexport void @_ZN13ExportMembers17virtualInlineDeclEv(%struct.ExportMembers* %this)
+ __declspec(dllexport) virtual void virtualDef();
+ __declspec(dllexport) virtual void virtualInclass() {}
+ __declspec(dllexport) virtual void virtualInlineDef();
+ __declspec(dllexport) virtual inline void virtualInlineDecl();
+
+ // MSC-DAG: define dso_local dllexport void @"?staticDef@ExportMembers@@SAXXZ"()
+ // MSC-DAG: define weak_odr dso_local dllexport void @"?staticInclass@ExportMembers@@SAXXZ"()
+ // MSC-DAG: define weak_odr dso_local dllexport void @"?staticInlineDef@ExportMembers@@SAXXZ"()
+ // MSC-DAG: define weak_odr dso_local dllexport void @"?staticInlineDecl@ExportMembers@@SAXXZ"()
+ // GNU-DAG: define dso_local dllexport void @_ZN13ExportMembers9staticDefEv()
+ // GNU-DAG: define weak_odr dso_local dllexport void @_ZN13ExportMembers13staticInclassEv()
+ // GNU-DAG: define weak_odr dso_local dllexport void @_ZN13ExportMembers15staticInlineDefEv()
+ // GNU-DAG: define weak_odr dso_local dllexport void @_ZN13ExportMembers16staticInlineDeclEv()
+ __declspec(dllexport) static void staticDef();
+ __declspec(dllexport) static void staticInclass() {}
+ __declspec(dllexport) static void staticInlineDef();
+ __declspec(dllexport) static inline void staticInlineDecl();
+
+ // M32-DAG: define dso_local dllexport x86_thiscallcc void @"?protectedDef@ExportMembers@@IAEXXZ"(%struct.ExportMembers* %this)
+ // M64-DAG: define dso_local dllexport void @"?protectedDef@ExportMembers@@IEAAXXZ"(%struct.ExportMembers* %this)
+ // G32-DAG: define dso_local dllexport x86_thiscallcc void @_ZN13ExportMembers12protectedDefEv(%struct.ExportMembers* %this)
+ // G64-DAG: define dso_local dllexport void @_ZN13ExportMembers12protectedDefEv(%struct.ExportMembers* %this)
+ // MSC-DAG: define dso_local dllexport void @"?protectedStaticDef@ExportMembers@@KAXXZ"()
+ // GNU-DAG: define dso_local dllexport void @_ZN13ExportMembers18protectedStaticDefEv()
+protected:
+ __declspec(dllexport) void protectedDef();
+ __declspec(dllexport) static void protectedStaticDef();
+
+ // M32-DAG: define dso_local dllexport x86_thiscallcc void @"?privateDef@ExportMembers@@AAEXXZ"(%struct.ExportMembers* %this)
+ // M64-DAG: define dso_local dllexport void @"?privateDef@ExportMembers@@AEAAXXZ"(%struct.ExportMembers* %this)
+ // G32-DAG: define dso_local dllexport x86_thiscallcc void @_ZN13ExportMembers10privateDefEv(%struct.ExportMembers* %this)
+ // G64-DAG: define dso_local dllexport void @_ZN13ExportMembers10privateDefEv(%struct.ExportMembers* %this)
+ // MSC-DAG: define dso_local dllexport void @"?privateStaticDef@ExportMembers@@CAXXZ"()
+ // GNU-DAG: define dso_local dllexport void @_ZN13ExportMembers16privateStaticDefEv()
+private:
+ __declspec(dllexport) void privateDef();
+ __declspec(dllexport) static void privateStaticDef();
+
+ // M32-DAG: define dso_local x86_thiscallcc void @"?ignored@ExportMembers@@QAEXXZ"(%struct.ExportMembers* %this)
+ // M64-DAG: define dso_local void @"?ignored@ExportMembers@@QEAAXXZ"(%struct.ExportMembers* %this)
+ // G32-DAG: define dso_local x86_thiscallcc void @_ZN13ExportMembers7ignoredEv(%struct.ExportMembers* %this)
+ // G64-DAG: define dso_local void @_ZN13ExportMembers7ignoredEv(%struct.ExportMembers* %this)
+public:
+ void ignored();
+
+ // MSC-DAG: @"?StaticField@ExportMembers@@2HA" = dso_local dllexport global i32 1, align 4
+ // MSC-DAG: @"?StaticConstField@ExportMembers@@2HB" = dso_local dllexport constant i32 1, align 4
+ // MSC-DAG: @"?StaticConstFieldEqualInit@ExportMembers@@2HB" = weak_odr dso_local dllexport constant i32 1, comdat, align 4
+ // MSC-DAG: @"?StaticConstFieldBraceInit@ExportMembers@@2HB" = weak_odr dso_local dllexport constant i32 1, comdat, align 4
+ // MSC-DAG: @"?StaticConstFieldRefNotDef@ExportMembers@@2HB" = weak_odr dso_local dllexport constant i32 1, comdat, align 4
+ // MSC-DAG: @"?ConstexprField@ExportMembers@@2HB" = weak_odr dso_local dllexport constant i32 1, comdat, align 4
+ // GNU-DAG: @_ZN13ExportMembers11StaticFieldE = dso_local dllexport global i32 1, align 4
+ // GNU-DAG: @_ZN13ExportMembers16StaticConstFieldE = dso_local dllexport constant i32 1, align 4
+ // GNU-DAG: @_ZN13ExportMembers25StaticConstFieldEqualInitE = dso_local dllexport constant i32 1, align 4
+ // GNU-DAG: @_ZN13ExportMembers25StaticConstFieldBraceInitE = dso_local dllexport constant i32 1, align 4
+ // GNU-DAG: @_ZN13ExportMembers14ConstexprFieldE = dso_local dllexport constant i32 1, align 4
+ __declspec(dllexport) static int StaticField;
+ __declspec(dllexport) static const int StaticConstField;
+ __declspec(dllexport) static const int StaticConstFieldEqualInit = 1;
+ __declspec(dllexport) static const int StaticConstFieldBraceInit{1};
+ __declspec(dllexport) static const int StaticConstFieldRefNotDef = 1;
+ __declspec(dllexport) constexpr static int ConstexprField = 1;
+};
+
+ void ExportMembers::normalDef() {}
+inline void ExportMembers::normalInlineDef() {}
+ void ExportMembers::normalInlineDecl() {}
+ void ExportMembers::virtualDef() {}
+inline void ExportMembers::virtualInlineDef() {}
+ void ExportMembers::virtualInlineDecl() {}
+ void ExportMembers::staticDef() {}
+inline void ExportMembers::staticInlineDef() {}
+ void ExportMembers::staticInlineDecl() {}
+ void ExportMembers::ignored() {}
+ void ExportMembers::protectedDef() {}
+ void ExportMembers::protectedStaticDef() {}
+ void ExportMembers::privateDef() {}
+ void ExportMembers::privateStaticDef() {}
+
+ int ExportMembers::StaticField = 1;
+const int ExportMembers::StaticConstField = 1;
+const int ExportMembers::StaticConstFieldEqualInit;
+const int ExportMembers::StaticConstFieldBraceInit;
+int foo() { return ExportMembers::StaticConstFieldRefNotDef; }
+constexpr int ExportMembers::ConstexprField;
+
+
+// Export individual members of a nested class.
+struct ExportMembers::Nested {
+ // M32-DAG: define dso_local dllexport x86_thiscallcc void @"?normalDef@Nested@ExportMembers@@QAEXXZ"(%"struct.ExportMembers::Nested"* %this)
+ // M64-DAG: define dso_local dllexport void @"?normalDef@Nested@ExportMembers@@QEAAXXZ"(%"struct.ExportMembers::Nested"* %this)
+ // M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?normalInclass@Nested@ExportMembers@@QAEXXZ"(%"struct.ExportMembers::Nested"* %this)
+ // M64-DAG: define weak_odr dso_local dllexport void @"?normalInclass@Nested@ExportMembers@@QEAAXXZ"(%"struct.ExportMembers::Nested"* %this)
+ // M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?normalInlineDef@Nested@ExportMembers@@QAEXXZ"(%"struct.ExportMembers::Nested"* %this)
+ // M64-DAG: define weak_odr dso_local dllexport void @"?normalInlineDef@Nested@ExportMembers@@QEAAXXZ"(%"struct.ExportMembers::Nested"* %this)
+ // M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?normalInlineDecl@Nested@ExportMembers@@QAEXXZ"(%"struct.ExportMembers::Nested"* %this)
+ // M64-DAG: define weak_odr dso_local dllexport void @"?normalInlineDecl@Nested@ExportMembers@@QEAAXXZ"(%"struct.ExportMembers::Nested"* %this)
+ // G32-DAG: define dso_local dllexport x86_thiscallcc void @_ZN13ExportMembers6Nested9normalDefEv(%"struct.ExportMembers::Nested"* %this)
+ // G64-DAG: define dso_local dllexport void @_ZN13ExportMembers6Nested9normalDefEv(%"struct.ExportMembers::Nested"* %this)
+ // G32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @_ZN13ExportMembers6Nested13normalInclassEv(%"struct.ExportMembers::Nested"* %this)
+ // G64-DAG: define weak_odr dso_local dllexport void @_ZN13ExportMembers6Nested13normalInclassEv(%"struct.ExportMembers::Nested"* %this)
+ // G32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @_ZN13ExportMembers6Nested15normalInlineDefEv(%"struct.ExportMembers::Nested"* %this)
+ // G64-DAG: define weak_odr dso_local dllexport void @_ZN13ExportMembers6Nested15normalInlineDefEv(%"struct.ExportMembers::Nested"* %this)
+ // G32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @_ZN13ExportMembers6Nested16normalInlineDeclEv(%"struct.ExportMembers::Nested"* %this)
+ // G64-DAG: define weak_odr dso_local dllexport void @_ZN13ExportMembers6Nested16normalInlineDeclEv(%"struct.ExportMembers::Nested"* %this)
+ __declspec(dllexport) void normalDef();
+ __declspec(dllexport) void normalInclass() {}
+ __declspec(dllexport) void normalInlineDef();
+ __declspec(dllexport) inline void normalInlineDecl();
+
+ // M32-DAG: define dso_local dllexport x86_thiscallcc void @"?virtualDef@Nested@ExportMembers@@UAEXXZ"(%"struct.ExportMembers::Nested"* %this)
+ // M64-DAG: define dso_local dllexport void @"?virtualDef@Nested@ExportMembers@@UEAAXXZ"(%"struct.ExportMembers::Nested"* %this)
+ // M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?virtualInclass@Nested@ExportMembers@@UAEXXZ"(%"struct.ExportMembers::Nested"* %this)
+ // M64-DAG: define weak_odr dso_local dllexport void @"?virtualInclass@Nested@ExportMembers@@UEAAXXZ"(%"struct.ExportMembers::Nested"* %this)
+ // M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?virtualInlineDef@Nested@ExportMembers@@UAEXXZ"(%"struct.ExportMembers::Nested"* %this)
+ // M64-DAG: define weak_odr dso_local dllexport void @"?virtualInlineDef@Nested@ExportMembers@@UEAAXXZ"(%"struct.ExportMembers::Nested"* %this)
+ // M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?virtualInlineDecl@Nested@ExportMembers@@UAEXXZ"(%"struct.ExportMembers::Nested"* %this)
+ // M64-DAG: define weak_odr dso_local dllexport void @"?virtualInlineDecl@Nested@ExportMembers@@UEAAXXZ"(%"struct.ExportMembers::Nested"* %this)
+ // G32-DAG: define dso_local dllexport x86_thiscallcc void @_ZN13ExportMembers6Nested10virtualDefEv(%"struct.ExportMembers::Nested"* %this)
+ // G64-DAG: define dso_local dllexport void @_ZN13ExportMembers6Nested10virtualDefEv(%"struct.ExportMembers::Nested"* %this)
+ // G32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @_ZN13ExportMembers6Nested14virtualInclassEv(%"struct.ExportMembers::Nested"* %this)
+ // G64-DAG: define weak_odr dso_local dllexport void @_ZN13ExportMembers6Nested14virtualInclassEv(%"struct.ExportMembers::Nested"* %this)
+ // G32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @_ZN13ExportMembers6Nested16virtualInlineDefEv(%"struct.ExportMembers::Nested"* %this)
+ // G64-DAG: define weak_odr dso_local dllexport void @_ZN13ExportMembers6Nested16virtualInlineDefEv(%"struct.ExportMembers::Nested"* %this)
+ // G32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @_ZN13ExportMembers6Nested17virtualInlineDeclEv(%"struct.ExportMembers::Nested"* %this)
+ // G64-DAG: define weak_odr dso_local dllexport void @_ZN13ExportMembers6Nested17virtualInlineDeclEv(%"struct.ExportMembers::Nested"* %this)
+ __declspec(dllexport) virtual void virtualDef();
+ __declspec(dllexport) virtual void virtualInclass() {}
+ __declspec(dllexport) virtual void virtualInlineDef();
+ __declspec(dllexport) virtual inline void virtualInlineDecl();
+
+ // MSC-DAG: define dso_local dllexport void @"?staticDef@Nested@ExportMembers@@SAXXZ"()
+ // MSC-DAG: define weak_odr dso_local dllexport void @"?staticInclass@Nested@ExportMembers@@SAXXZ"()
+ // MSC-DAG: define weak_odr dso_local dllexport void @"?staticInlineDef@Nested@ExportMembers@@SAXXZ"()
+ // MSC-DAG: define weak_odr dso_local dllexport void @"?staticInlineDecl@Nested@ExportMembers@@SAXXZ"()
+ // GNU-DAG: define dso_local dllexport void @_ZN13ExportMembers6Nested9staticDefEv()
+ // GNU-DAG: define weak_odr dso_local dllexport void @_ZN13ExportMembers6Nested13staticInclassEv()
+ // GNU-DAG: define weak_odr dso_local dllexport void @_ZN13ExportMembers6Nested15staticInlineDefEv()
+ // GNU-DAG: define weak_odr dso_local dllexport void @_ZN13ExportMembers6Nested16staticInlineDeclEv()
+ __declspec(dllexport) static void staticDef();
+ __declspec(dllexport) static void staticInclass() {}
+ __declspec(dllexport) static void staticInlineDef();
+ __declspec(dllexport) static inline void staticInlineDecl();
+
+ // M32-DAG: define dso_local dllexport x86_thiscallcc void @"?protectedDef@Nested@ExportMembers@@IAEXXZ"(%"struct.ExportMembers::Nested"* %this)
+ // M64-DAG: define dso_local dllexport void @"?protectedDef@Nested@ExportMembers@@IEAAXXZ"(%"struct.ExportMembers::Nested"* %this)
+ // G32-DAG: define dso_local dllexport x86_thiscallcc void @_ZN13ExportMembers6Nested12protectedDefEv(%"struct.ExportMembers::Nested"* %this)
+ // G64-DAG: define dso_local dllexport void @_ZN13ExportMembers6Nested12protectedDefEv(%"struct.ExportMembers::Nested"* %this)
+ // MSC-DAG: define dso_local dllexport void @"?protectedStaticDef@Nested@ExportMembers@@KAXXZ"()
+ // GNU-DAG: define dso_local dllexport void @_ZN13ExportMembers6Nested18protectedStaticDefEv()
+protected:
+ __declspec(dllexport) void protectedDef();
+ __declspec(dllexport) static void protectedStaticDef();
+
+ // M32-DAG: define dso_local dllexport x86_thiscallcc void @"?privateDef@Nested@ExportMembers@@AAEXXZ"(%"struct.ExportMembers::Nested"* %this)
+ // M64-DAG: define dso_local dllexport void @"?privateDef@Nested@ExportMembers@@AEAAXXZ"(%"struct.ExportMembers::Nested"* %this)
+ // G32-DAG: define dso_local dllexport x86_thiscallcc void @_ZN13ExportMembers6Nested10privateDefEv(%"struct.ExportMembers::Nested"* %this)
+ // G64-DAG: define dso_local dllexport void @_ZN13ExportMembers6Nested10privateDefEv(%"struct.ExportMembers::Nested"* %this)
+ // MSC-DAG: define dso_local dllexport void @"?privateStaticDef@Nested@ExportMembers@@CAXXZ"()
+ // GNU-DAG: define dso_local dllexport void @_ZN13ExportMembers6Nested16privateStaticDefEv()
+private:
+ __declspec(dllexport) void privateDef();
+ __declspec(dllexport) static void privateStaticDef();
+
+ // M32-DAG: define dso_local x86_thiscallcc void @"?ignored@Nested@ExportMembers@@QAEXXZ"(%"struct.ExportMembers::Nested"* %this)
+ // M64-DAG: define dso_local void @"?ignored@Nested@ExportMembers@@QEAAXXZ"(%"struct.ExportMembers::Nested"* %this)
+ // G32-DAG: define dso_local x86_thiscallcc void @_ZN13ExportMembers6Nested7ignoredEv(%"struct.ExportMembers::Nested"* %this)
+ // G64-DAG: define dso_local void @_ZN13ExportMembers6Nested7ignoredEv(%"struct.ExportMembers::Nested"* %this)
+public:
+ void ignored();
+
+ // MSC-DAG: @"?StaticField@Nested@ExportMembers@@2HA" = dso_local dllexport global i32 1, align 4
+ // MSC-DAG: @"?StaticConstField@Nested@ExportMembers@@2HB" = dso_local dllexport constant i32 1, align 4
+ // MSC-DAG: @"?StaticConstFieldEqualInit@Nested@ExportMembers@@2HB" = weak_odr dso_local dllexport constant i32 1, comdat, align 4
+ // MSC-DAG: @"?StaticConstFieldBraceInit@Nested@ExportMembers@@2HB" = weak_odr dso_local dllexport constant i32 1, comdat, align 4
+ // MSC-DAG: @"?StaticConstFieldRefNotDef@Nested@ExportMembers@@2HB" = weak_odr dso_local dllexport constant i32 1, comdat, align 4
+ // MSC-DAG: @"?ConstexprField@Nested@ExportMembers@@2HB" = weak_odr dso_local dllexport constant i32 1, comdat, align 4
+ // GNU-DAG: @_ZN13ExportMembers6Nested11StaticFieldE = dso_local dllexport global i32 1, align 4
+ // GNU-DAG: @_ZN13ExportMembers6Nested16StaticConstFieldE = dso_local dllexport constant i32 1, align 4
+ // GNU-DAG: @_ZN13ExportMembers6Nested25StaticConstFieldEqualInitE = dso_local dllexport constant i32 1, align 4
+ // GNU-DAG: @_ZN13ExportMembers6Nested25StaticConstFieldBraceInitE = dso_local dllexport constant i32 1, align 4
+ // GNU-DAG: @_ZN13ExportMembers6Nested14ConstexprFieldE = dso_local dllexport constant i32 1, align 4
+ __declspec(dllexport) static int StaticField;
+ __declspec(dllexport) static const int StaticConstField;
+ __declspec(dllexport) static const int StaticConstFieldEqualInit = 1;
+ __declspec(dllexport) static const int StaticConstFieldBraceInit{1};
+ __declspec(dllexport) static const int StaticConstFieldRefNotDef = 1;
+ __declspec(dllexport) constexpr static int ConstexprField = 1;
+};
+
+ void ExportMembers::Nested::normalDef() {}
+inline void ExportMembers::Nested::normalInlineDef() {}
+ void ExportMembers::Nested::normalInlineDecl() {}
+ void ExportMembers::Nested::virtualDef() {}
+inline void ExportMembers::Nested::virtualInlineDef() {}
+ void ExportMembers::Nested::virtualInlineDecl() {}
+ void ExportMembers::Nested::staticDef() {}
+inline void ExportMembers::Nested::staticInlineDef() {}
+ void ExportMembers::Nested::staticInlineDecl() {}
+ void ExportMembers::Nested::ignored() {}
+ void ExportMembers::Nested::protectedDef() {}
+ void ExportMembers::Nested::protectedStaticDef() {}
+ void ExportMembers::Nested::privateDef() {}
+ void ExportMembers::Nested::privateStaticDef() {}
+
+ int ExportMembers::Nested::StaticField = 1;
+const int ExportMembers::Nested::StaticConstField = 1;
+const int ExportMembers::Nested::StaticConstFieldEqualInit;
+const int ExportMembers::Nested::StaticConstFieldBraceInit;
+int fooNested() { return ExportMembers::Nested::StaticConstFieldRefNotDef; }
+constexpr int ExportMembers::Nested::ConstexprField;
+
+
+// Export special member functions.
+struct ExportSpecials {
+ // M32-DAG: define dso_local dllexport x86_thiscallcc %struct.ExportSpecials* @"??0ExportSpecials@@QAE@XZ"(%struct.ExportSpecials* returned %this)
+ // M64-DAG: define dso_local dllexport %struct.ExportSpecials* @"??0ExportSpecials@@QEAA@XZ"(%struct.ExportSpecials* returned %this)
+ // G32-DAG: define dso_local dllexport x86_thiscallcc void @_ZN14ExportSpecialsC1Ev(%struct.ExportSpecials* %this)
+ // G64-DAG: define dso_local dllexport void @_ZN14ExportSpecialsC1Ev(%struct.ExportSpecials* %this)
+ // G32-DAG: define dso_local dllexport x86_thiscallcc void @_ZN14ExportSpecialsC2Ev(%struct.ExportSpecials* %this)
+ // G64-DAG: define dso_local dllexport void @_ZN14ExportSpecialsC2Ev(%struct.ExportSpecials* %this)
+ __declspec(dllexport) ExportSpecials();
+
+ // M32-DAG: define dso_local dllexport x86_thiscallcc void @"??1ExportSpecials@@QAE@XZ"(%struct.ExportSpecials* %this)
+ // M64-DAG: define dso_local dllexport void @"??1ExportSpecials@@QEAA@XZ"(%struct.ExportSpecials* %this)
+ // G32-DAG: define dso_local dllexport x86_thiscallcc void @_ZN14ExportSpecialsD1Ev(%struct.ExportSpecials* %this)
+ // G64-DAG: define dso_local dllexport void @_ZN14ExportSpecialsD1Ev(%struct.ExportSpecials* %this)
+ // G32-DAG: define dso_local dllexport x86_thiscallcc void @_ZN14ExportSpecialsD2Ev(%struct.ExportSpecials* %this)
+ // G64-DAG: define dso_local dllexport void @_ZN14ExportSpecialsD2Ev(%struct.ExportSpecials* %this)
+ __declspec(dllexport) ~ExportSpecials();
+
+ // M32-DAG: define dso_local dllexport x86_thiscallcc %struct.ExportSpecials* @"??0ExportSpecials@@QAE@ABU0@@Z"(%struct.ExportSpecials* returned %this, %struct.ExportSpecials* dereferenceable({{[0-9]+}}))
+ // M64-DAG: define dso_local dllexport %struct.ExportSpecials* @"??0ExportSpecials@@QEAA@AEBU0@@Z"(%struct.ExportSpecials* returned %this, %struct.ExportSpecials* dereferenceable({{[0-9]+}}))
+ // G32-DAG: define dso_local dllexport x86_thiscallcc void @_ZN14ExportSpecialsC1ERKS_(%struct.ExportSpecials* %this, %struct.ExportSpecials* dereferenceable({{[0-9]+}}))
+ // G64-DAG: define dso_local dllexport void @_ZN14ExportSpecialsC1ERKS_(%struct.ExportSpecials* %this, %struct.ExportSpecials* dereferenceable({{[0-9]+}}))
+ // G32-DAG: define dso_local dllexport x86_thiscallcc void @_ZN14ExportSpecialsC2ERKS_(%struct.ExportSpecials* %this, %struct.ExportSpecials* dereferenceable({{[0-9]+}}))
+ // G64-DAG: define dso_local dllexport void @_ZN14ExportSpecialsC2ERKS_(%struct.ExportSpecials* %this, %struct.ExportSpecials* dereferenceable({{[0-9]+}}))
+ __declspec(dllexport) ExportSpecials(const ExportSpecials&);
+
+ // M32-DAG: define dso_local dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ExportSpecials* @"??4ExportSpecials@@QAEAAU0@ABU0@@Z"(%struct.ExportSpecials* %this, %struct.ExportSpecials* dereferenceable({{[0-9]+}}))
+ // M64-DAG: define dso_local dllexport dereferenceable({{[0-9]+}}) %struct.ExportSpecials* @"??4ExportSpecials@@QEAAAEAU0@AEBU0@@Z"(%struct.ExportSpecials* %this, %struct.ExportSpecials* dereferenceable({{[0-9]+}}))
+ // G32-DAG: define dso_local dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ExportSpecials* @_ZN14ExportSpecialsaSERKS_(%struct.ExportSpecials* %this, %struct.ExportSpecials* dereferenceable({{[0-9]+}}))
+ // G64-DAG: define dso_local dllexport dereferenceable({{[0-9]+}}) %struct.ExportSpecials* @_ZN14ExportSpecialsaSERKS_(%struct.ExportSpecials* %this, %struct.ExportSpecials* dereferenceable({{[0-9]+}}))
+ __declspec(dllexport) ExportSpecials& operator=(const ExportSpecials&);
+
+ // M32-DAG: define dso_local dllexport x86_thiscallcc %struct.ExportSpecials* @"??0ExportSpecials@@QAE@$$QAU0@@Z"(%struct.ExportSpecials* returned %this, %struct.ExportSpecials* dereferenceable({{[0-9]+}}))
+ // M64-DAG: define dso_local dllexport %struct.ExportSpecials* @"??0ExportSpecials@@QEAA@$$QEAU0@@Z"(%struct.ExportSpecials* returned %this, %struct.ExportSpecials* dereferenceable({{[0-9]+}}))
+ // G32-DAG: define dso_local dllexport x86_thiscallcc void @_ZN14ExportSpecialsC1EOS_(%struct.ExportSpecials* %this, %struct.ExportSpecials* dereferenceable({{[0-9]+}}))
+ // G64-DAG: define dso_local dllexport void @_ZN14ExportSpecialsC1EOS_(%struct.ExportSpecials* %this, %struct.ExportSpecials* dereferenceable({{[0-9]+}}))
+ // G32-DAG: define dso_local dllexport x86_thiscallcc void @_ZN14ExportSpecialsC2EOS_(%struct.ExportSpecials* %this, %struct.ExportSpecials* dereferenceable({{[0-9]+}}))
+ // G64-DAG: define dso_local dllexport void @_ZN14ExportSpecialsC2EOS_(%struct.ExportSpecials* %this, %struct.ExportSpecials* dereferenceable({{[0-9]+}}))
+ __declspec(dllexport) ExportSpecials(ExportSpecials&&);
+
+ // M32-DAG: define dso_local dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ExportSpecials* @"??4ExportSpecials@@QAEAAU0@$$QAU0@@Z"(%struct.ExportSpecials* %this, %struct.ExportSpecials* dereferenceable({{[0-9]+}}))
+ // M64-DAG: define dso_local dllexport dereferenceable({{[0-9]+}}) %struct.ExportSpecials* @"??4ExportSpecials@@QEAAAEAU0@$$QEAU0@@Z"(%struct.ExportSpecials* %this, %struct.ExportSpecials* dereferenceable({{[0-9]+}}))
+ // G32-DAG: define dso_local dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ExportSpecials* @_ZN14ExportSpecialsaSEOS_(%struct.ExportSpecials* %this, %struct.ExportSpecials* dereferenceable({{[0-9]+}}))
+ // G64-DAG: define dso_local dllexport dereferenceable({{[0-9]+}}) %struct.ExportSpecials* @_ZN14ExportSpecialsaSEOS_(%struct.ExportSpecials* %this, %struct.ExportSpecials* dereferenceable({{[0-9]+}}))
+ __declspec(dllexport) ExportSpecials& operator=(ExportSpecials&&);
+};
+ExportSpecials::ExportSpecials() {}
+ExportSpecials::~ExportSpecials() {}
+ExportSpecials::ExportSpecials(const ExportSpecials&) {}
+ExportSpecials& ExportSpecials::operator=(const ExportSpecials&) { return *this; }
+ExportSpecials::ExportSpecials(ExportSpecials&&) {}
+ExportSpecials& ExportSpecials::operator=(ExportSpecials&&) { return *this; }
+
+
+// Export class with inline special member functions.
+struct ExportInlineSpecials {
+ // M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc %struct.ExportInlineSpecials* @"??0ExportInlineSpecials@@QAE@XZ"(%struct.ExportInlineSpecials* returned %this)
+ // M64-DAG: define weak_odr dso_local dllexport %struct.ExportInlineSpecials* @"??0ExportInlineSpecials@@QEAA@XZ"(
+ // G32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @_ZN20ExportInlineSpecialsC1Ev(
+ // G64-DAG: define weak_odr dso_local dllexport void @_ZN20ExportInlineSpecialsC1Ev(
+ __declspec(dllexport) ExportInlineSpecials() {}
+
+ // M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"??1ExportInlineSpecials@@QAE@XZ"(
+ // M64-DAG: define weak_odr dso_local dllexport void @"??1ExportInlineSpecials@@QEAA@XZ"(
+ // G32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @_ZN20ExportInlineSpecialsD1Ev(
+ // G64-DAG: define weak_odr dso_local dllexport void @_ZN20ExportInlineSpecialsD1Ev(
+ __declspec(dllexport) ~ExportInlineSpecials() {}
+
+ // M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc %struct.ExportInlineSpecials* @"??0ExportInlineSpecials@@QAE@ABU0@@Z"(
+ // M64-DAG: define weak_odr dso_local dllexport %struct.ExportInlineSpecials* @"??0ExportInlineSpecials@@QEAA@AEBU0@@Z"(
+ // G32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @_ZN20ExportInlineSpecialsC1ERKS_(
+ // G64-DAG: define weak_odr dso_local dllexport void @_ZN20ExportInlineSpecialsC1ERKS_(
+ __declspec(dllexport) inline ExportInlineSpecials(const ExportInlineSpecials&);
+
+ // M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ExportInlineSpecials* @"??4ExportInlineSpecials@@QAEAAU0@ABU0@@Z"(
+ // M64-DAG: define weak_odr dso_local dllexport dereferenceable({{[0-9]+}}) %struct.ExportInlineSpecials* @"??4ExportInlineSpecials@@QEAAAEAU0@AEBU0@@Z"(
+ // G32-DAG: define weak_odr dso_local dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ExportInlineSpecials* @_ZN20ExportInlineSpecialsaSERKS_(
+ // G64-DAG: define weak_odr dso_local dllexport dereferenceable({{[0-9]+}}) %struct.ExportInlineSpecials* @_ZN20ExportInlineSpecialsaSERKS_(
+ __declspec(dllexport) ExportInlineSpecials& operator=(const ExportInlineSpecials&);
+
+ // M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc %struct.ExportInlineSpecials* @"??0ExportInlineSpecials@@QAE@$$QAU0@@Z"(
+ // M64-DAG: define weak_odr dso_local dllexport %struct.ExportInlineSpecials* @"??0ExportInlineSpecials@@QEAA@$$QEAU0@@Z"(
+ // G32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @_ZN20ExportInlineSpecialsC1EOS_(
+ // G64-DAG: define weak_odr dso_local dllexport void @_ZN20ExportInlineSpecialsC1EOS_(
+ __declspec(dllexport) ExportInlineSpecials(ExportInlineSpecials&&) {}
+
+ // M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ExportInlineSpecials* @"??4ExportInlineSpecials@@QAEAAU0@$$QAU0@@Z"(
+ // M64-DAG: define weak_odr dso_local dllexport dereferenceable({{[0-9]+}}) %struct.ExportInlineSpecials* @"??4ExportInlineSpecials@@QEAAAEAU0@$$QEAU0@@Z"(
+ // G32-DAG: define weak_odr dso_local dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ExportInlineSpecials* @_ZN20ExportInlineSpecialsaSEOS_(
+ // G64-DAG: define weak_odr dso_local dllexport dereferenceable({{[0-9]+}}) %struct.ExportInlineSpecials* @_ZN20ExportInlineSpecialsaSEOS_(
+ __declspec(dllexport) ExportInlineSpecials& operator=(ExportInlineSpecials&&) { return *this; }
+};
+ExportInlineSpecials::ExportInlineSpecials(const ExportInlineSpecials&) {}
+inline ExportInlineSpecials& ExportInlineSpecials::operator=(const ExportInlineSpecials&) { return *this; }
+
+
+// Export defaulted member function definitions.
+struct ExportDefaultedDefs {
+ __declspec(dllexport) ExportDefaultedDefs();
+ __declspec(dllexport) ~ExportDefaultedDefs();
+ __declspec(dllexport) inline ExportDefaultedDefs(const ExportDefaultedDefs&);
+ __declspec(dllexport) ExportDefaultedDefs& operator=(const ExportDefaultedDefs&);
+ __declspec(dllexport) ExportDefaultedDefs(ExportDefaultedDefs&&);
+ __declspec(dllexport) ExportDefaultedDefs& operator=(ExportDefaultedDefs&&);
+};
+
+// M32-DAG: define dso_local dllexport x86_thiscallcc %struct.ExportDefaultedDefs* @"??0ExportDefaultedDefs@@QAE@XZ"(%struct.ExportDefaultedDefs* returned %this)
+// M64-DAG: define dso_local dllexport %struct.ExportDefaultedDefs* @"??0ExportDefaultedDefs@@QEAA@XZ"(%struct.ExportDefaultedDefs* returned %this)
+// G32-DAG: define dso_local dllexport x86_thiscallcc void @_ZN19ExportDefaultedDefsC1Ev(%struct.ExportDefaultedDefs* %this)
+// G64-DAG: define dso_local dllexport void @_ZN19ExportDefaultedDefsC1Ev(%struct.ExportDefaultedDefs* %this)
+// G32-DAG: define dso_local dllexport x86_thiscallcc void @_ZN19ExportDefaultedDefsC2Ev(%struct.ExportDefaultedDefs* %this)
+// G64-DAG: define dso_local dllexport void @_ZN19ExportDefaultedDefsC2Ev(%struct.ExportDefaultedDefs* %this)
+__declspec(dllexport) ExportDefaultedDefs::ExportDefaultedDefs() = default;
+
+// M32-DAG: define dso_local dllexport x86_thiscallcc void @"??1ExportDefaultedDefs@@QAE@XZ"(%struct.ExportDefaultedDefs* %this)
+// M64-DAG: define dso_local dllexport void @"??1ExportDefaultedDefs@@QEAA@XZ"(%struct.ExportDefaultedDefs* %this)
+// G32-DAG: define dso_local dllexport x86_thiscallcc void @_ZN19ExportDefaultedDefsD1Ev(%struct.ExportDefaultedDefs* %this)
+// G64-DAG: define dso_local dllexport void @_ZN19ExportDefaultedDefsD1Ev(%struct.ExportDefaultedDefs* %this)
+// G32-DAG: define dso_local dllexport x86_thiscallcc void @_ZN19ExportDefaultedDefsD2Ev(%struct.ExportDefaultedDefs* %this)
+// G64-DAG: define dso_local dllexport void @_ZN19ExportDefaultedDefsD2Ev(%struct.ExportDefaultedDefs* %this)
+ExportDefaultedDefs::~ExportDefaultedDefs() = default;
+
+// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc %struct.ExportDefaultedDefs* @"??0ExportDefaultedDefs@@QAE@ABU0@@Z"(%struct.ExportDefaultedDefs* returned %this, %struct.ExportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// M64-DAG: define weak_odr dso_local dllexport %struct.ExportDefaultedDefs* @"??0ExportDefaultedDefs@@QEAA@AEBU0@@Z"(%struct.ExportDefaultedDefs* returned %this, %struct.ExportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// G32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @_ZN19ExportDefaultedDefsC1ERKS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// G64-DAG: define weak_odr dso_local dllexport void @_ZN19ExportDefaultedDefsC1ERKS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// G32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @_ZN19ExportDefaultedDefsC2ERKS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// G64-DAG: define weak_odr dso_local dllexport void @_ZN19ExportDefaultedDefsC2ERKS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* dereferenceable({{[0-9]+}}))
+__declspec(dllexport) ExportDefaultedDefs::ExportDefaultedDefs(const ExportDefaultedDefs&) = default;
+
+// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ExportDefaultedDefs* @"??4ExportDefaultedDefs@@QAEAAU0@ABU0@@Z"(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// M64-DAG: define weak_odr dso_local dllexport dereferenceable({{[0-9]+}}) %struct.ExportDefaultedDefs* @"??4ExportDefaultedDefs@@QEAAAEAU0@AEBU0@@Z"(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// G32-DAG: define weak_odr dso_local dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ExportDefaultedDefs* @_ZN19ExportDefaultedDefsaSERKS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// G64-DAG: define weak_odr dso_local dllexport dereferenceable({{[0-9]+}}) %struct.ExportDefaultedDefs* @_ZN19ExportDefaultedDefsaSERKS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* dereferenceable({{[0-9]+}}))
+inline ExportDefaultedDefs& ExportDefaultedDefs::operator=(const ExportDefaultedDefs&) = default;
+
+// M32-DAG: define dso_local dllexport x86_thiscallcc %struct.ExportDefaultedDefs* @"??0ExportDefaultedDefs@@QAE@$$QAU0@@Z"(%struct.ExportDefaultedDefs* returned %this, %struct.ExportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// M64-DAG: define dso_local dllexport %struct.ExportDefaultedDefs* @"??0ExportDefaultedDefs@@QEAA@$$QEAU0@@Z"(%struct.ExportDefaultedDefs* returned %this, %struct.ExportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// G32-DAG: define dso_local dllexport x86_thiscallcc void @_ZN19ExportDefaultedDefsC1EOS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// G64-DAG: define dso_local dllexport void @_ZN19ExportDefaultedDefsC1EOS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// G32-DAG: define dso_local dllexport x86_thiscallcc void @_ZN19ExportDefaultedDefsC2EOS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// G64-DAG: define dso_local dllexport void @_ZN19ExportDefaultedDefsC2EOS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* dereferenceable({{[0-9]+}}))
+__declspec(dllexport) ExportDefaultedDefs::ExportDefaultedDefs(ExportDefaultedDefs&&) = default;
+
+// M32-DAG: define dso_local dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ExportDefaultedDefs* @"??4ExportDefaultedDefs@@QAEAAU0@$$QAU0@@Z"(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// M64-DAG: define dso_local dllexport dereferenceable({{[0-9]+}}) %struct.ExportDefaultedDefs* @"??4ExportDefaultedDefs@@QEAAAEAU0@$$QEAU0@@Z"(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// G32-DAG: define dso_local dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ExportDefaultedDefs* @_ZN19ExportDefaultedDefsaSEOS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// G64-DAG: define dso_local dllexport dereferenceable({{[0-9]+}}) %struct.ExportDefaultedDefs* @_ZN19ExportDefaultedDefsaSEOS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* dereferenceable({{[0-9]+}}))
+ExportDefaultedDefs& ExportDefaultedDefs::operator=(ExportDefaultedDefs&&) = default;
+
+
+// Export defaulted member function definitions declared inside class.
+struct ExportDefaultedInclassDefs {
+ __declspec(dllexport) ExportDefaultedInclassDefs() = default;
+ // M32VS2013-DAG: define weak_odr dso_local dllexport x86_thiscallcc %struct.ExportDefaultedInclassDefs* @"??0ExportDefaultedInclassDefs@@QAE@XZ"(%struct.ExportDefaultedInclassDefs* returned %this)
+ // M64VS2013-DAG: define weak_odr dso_local dllexport %struct.ExportDefaultedInclassDefs* @"??0ExportDefaultedInclassDefs@@QEAA@XZ"(%struct.ExportDefaultedInclassDefs* returned %this)
+ // M32VS2015-NOT: define weak_odr dso_local dllexport x86_thiscallcc %struct.ExportDefaultedInclassDefs* @"??0ExportDefaultedInclassDefs@@QAE@XZ"(%struct.ExportDefaultedInclassDefs* returned %this)
+ // M64VS2015-NOT: define weak_odr dso_local dllexport %struct.ExportDefaultedInclassDefs* @"??0ExportDefaultedInclassDefs@@QEAA@XZ"(%struct.ExportDefaultedInclassDefs* returned %this)
+
+ __declspec(dllexport) ~ExportDefaultedInclassDefs() = default;
+ // M32VS2013-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"??1ExportDefaultedInclassDefs@@QAE@XZ"(%struct.ExportDefaultedInclassDefs* %this)
+ // M64VS2013-DAG: define weak_odr dso_local dllexport void @"??1ExportDefaultedInclassDefs@@QEAA@XZ"(%struct.ExportDefaultedInclassDefs* %this)
+ // M32VS2015-NOT: define weak_odr dso_local dllexport x86_thiscallcc void @"??1ExportDefaultedInclassDefs@@QAE@XZ"(%struct.ExportDefaultedInclassDefs* %this)
+ // M64VS2015-NOT: define weak_odr dso_local dllexport void @"??1ExportDefaultedInclassDefs@@QEAA@XZ"(%struct.ExportDefaultedInclassDefs* %this)
+
+ __declspec(dllexport) ExportDefaultedInclassDefs(const ExportDefaultedInclassDefs&) = default;
+ // M32VS2013-DAG: define weak_odr dso_local dllexport x86_thiscallcc %struct.ExportDefaultedInclassDefs* @"??0ExportDefaultedInclassDefs@@QAE@ABU0@@Z"(%struct.ExportDefaultedInclassDefs* returned %this, %struct.ExportDefaultedInclassDefs* dereferenceable({{[0-9]+}}))
+ // M64VS2013-DAG: define weak_odr dso_local dllexport %struct.ExportDefaultedInclassDefs* @"??0ExportDefaultedInclassDefs@@QEAA@AEBU0@@Z"(%struct.ExportDefaultedInclassDefs* returned %this, %struct.ExportDefaultedInclassDefs* dereferenceable({{[0-9]+}}))
+ // M32VS2015-NOT: define weak_odr dso_local dllexport x86_thiscallcc %struct.ExportDefaultedInclassDefs* @"??0ExportDefaultedInclassDefs@@QAE@ABU0@@Z"(%struct.ExportDefaultedInclassDefs* returned %this, %struct.ExportDefaultedInclassDefs* dereferenceable({{[0-9]+}}))
+ // M64VS2015-NOT: define weak_odr dso_local dllexport %struct.ExportDefaultedInclassDefs* @"??0ExportDefaultedInclassDefs@@QEAA@AEBU0@@Z"(%struct.ExportDefaultedInclassDefs* returned %this, %struct.ExportDefaultedInclassDefs* dereferenceable({{[0-9]+}}))
+
+ __declspec(dllexport) ExportDefaultedInclassDefs& operator=(const ExportDefaultedInclassDefs&) = default;
+ // M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ExportDefaultedInclassDefs* @"??4ExportDefaultedInclassDefs@@QAEAAU0@ABU0@@Z"(%struct.ExportDefaultedInclassDefs* %this, %struct.ExportDefaultedInclassDefs* dereferenceable({{[0-9]+}}))
+ // M64-DAG: define weak_odr dso_local dllexport dereferenceable({{[0-9]+}}) %struct.ExportDefaultedInclassDefs* @"??4ExportDefaultedInclassDefs@@QEAAAEAU0@AEBU0@@Z"(%struct.ExportDefaultedInclassDefs* %this, %struct.ExportDefaultedInclassDefs* dereferenceable({{[0-9]+}}))
+};
+
+
+// Export allocation functions.
+struct ExportAlloc {
+ __declspec(dllexport) void* operator new(__SIZE_TYPE__);
+ __declspec(dllexport) void* operator new[](__SIZE_TYPE__);
+ __declspec(dllexport) void operator delete(void*);
+ __declspec(dllexport) void operator delete[](void*);
+};
+
+// M32-DAG: define dso_local dllexport i8* @"??2ExportAlloc@@SAPAXI@Z"(i32 %n)
+// M64-DAG: define dso_local dllexport i8* @"??2ExportAlloc@@SAPEAX_K@Z"(i64 %n)
+// G32-DAG: define dso_local dllexport i8* @_ZN11ExportAllocnwEj(i32 %n)
+// G64-DAG: define dso_local dllexport i8* @_ZN11ExportAllocnwEy(i64 %n)
+void* ExportAlloc::operator new(__SIZE_TYPE__ n) { return malloc(n); }
+
+// M32-DAG: define dso_local dllexport i8* @"??_UExportAlloc@@SAPAXI@Z"(i32 %n)
+// M64-DAG: define dso_local dllexport i8* @"??_UExportAlloc@@SAPEAX_K@Z"(i64 %n)
+// G32-DAG: define dso_local dllexport i8* @_ZN11ExportAllocnaEj(i32 %n)
+// G64-DAG: define dso_local dllexport i8* @_ZN11ExportAllocnaEy(i64 %n)
+void* ExportAlloc::operator new[](__SIZE_TYPE__ n) { return malloc(n); }
+
+// M32-DAG: define dso_local dllexport void @"??3ExportAlloc@@SAXPAX@Z"(i8* %p)
+// M64-DAG: define dso_local dllexport void @"??3ExportAlloc@@SAXPEAX@Z"(i8* %p)
+// G32-DAG: define dso_local dllexport void @_ZN11ExportAllocdlEPv(i8* %p)
+// G64-DAG: define dso_local dllexport void @_ZN11ExportAllocdlEPv(i8* %p)
+void ExportAlloc::operator delete(void* p) { free(p); }
+
+// M32-DAG: define dso_local dllexport void @"??_VExportAlloc@@SAXPAX@Z"(i8* %p)
+// M64-DAG: define dso_local dllexport void @"??_VExportAlloc@@SAXPEAX@Z"(i8* %p)
+// G32-DAG: define dso_local dllexport void @_ZN11ExportAllocdaEPv(i8* %p)
+// G64-DAG: define dso_local dllexport void @_ZN11ExportAllocdaEPv(i8* %p)
+void ExportAlloc::operator delete[](void* p) { free(p); }
+
+
+//===----------------------------------------------------------------------===//
+// Class member templates
+//===----------------------------------------------------------------------===//
+
+struct MemFunTmpl {
+ template<typename T> void normalDef() {}
+ template<typename T> __declspec(dllexport) void exportedNormal() {}
+ template<typename T> static void staticDef() {}
+ template<typename T> __declspec(dllexport) static void exportedStatic() {}
+};
+
+// Export implicit instantiation of an exported member function template.
+void useMemFunTmpl() {
+ // M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"??$exportedNormal@UImplicitInst_Exported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl* %this)
+ // M64-DAG: define weak_odr dso_local dllexport void @"??$exportedNormal@UImplicitInst_Exported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl* %this)
+ // G32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @_ZN10MemFunTmpl14exportedNormalI21ImplicitInst_ExportedEEvv(%struct.MemFunTmpl* %this)
+ // G64-DAG: define weak_odr dso_local dllexport void @_ZN10MemFunTmpl14exportedNormalI21ImplicitInst_ExportedEEvv(%struct.MemFunTmpl* %this)
+ MemFunTmpl().exportedNormal<ImplicitInst_Exported>();
+
+ // MSC-DAG: define weak_odr dso_local dllexport void @"??$exportedStatic@UImplicitInst_Exported@@@MemFunTmpl@@SAXXZ"()
+ // GNU-DAG: define weak_odr dso_local dllexport void @_ZN10MemFunTmpl14exportedStaticI21ImplicitInst_ExportedEEvv()
+ MemFunTmpl().exportedStatic<ImplicitInst_Exported>();
+}
+
+
+// Export explicit instantiation declaration of an exported member function
+// template.
+// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"??$exportedNormal@UExplicitDecl_Exported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl* %this)
+// M64-DAG: define weak_odr dso_local dllexport void @"??$exportedNormal@UExplicitDecl_Exported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl* %this)
+// G32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @_ZN10MemFunTmpl14exportedNormalI21ExplicitDecl_ExportedEEvv(%struct.MemFunTmpl* %this)
+// G64-DAG: define weak_odr dso_local dllexport void @_ZN10MemFunTmpl14exportedNormalI21ExplicitDecl_ExportedEEvv(%struct.MemFunTmpl* %this)
+extern template void MemFunTmpl::exportedNormal<ExplicitDecl_Exported>();
+ template void MemFunTmpl::exportedNormal<ExplicitDecl_Exported>();
+
+// MSC-DAG: define weak_odr dso_local dllexport void @"??$exportedStatic@UExplicitDecl_Exported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: define weak_odr dso_local dllexport void @_ZN10MemFunTmpl14exportedStaticI21ExplicitDecl_ExportedEEvv()
+extern template void MemFunTmpl::exportedStatic<ExplicitDecl_Exported>();
+ template void MemFunTmpl::exportedStatic<ExplicitDecl_Exported>();
+
+
+// Export explicit instantiation definition of an exported member function
+// template.
+// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"??$exportedNormal@UExplicitInst_Exported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl* %this)
+// M64-DAG: define weak_odr dso_local dllexport void @"??$exportedNormal@UExplicitInst_Exported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl* %this)
+// G32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @_ZN10MemFunTmpl14exportedNormalI21ExplicitInst_ExportedEEvv(%struct.MemFunTmpl* %this)
+// G64-DAG: define weak_odr dso_local dllexport void @_ZN10MemFunTmpl14exportedNormalI21ExplicitInst_ExportedEEvv(%struct.MemFunTmpl* %this)
+template void MemFunTmpl::exportedNormal<ExplicitInst_Exported>();
+
+// MSC-DAG: define weak_odr dso_local dllexport void @"??$exportedStatic@UExplicitInst_Exported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: define weak_odr dso_local dllexport void @_ZN10MemFunTmpl14exportedStaticI21ExplicitInst_ExportedEEvv()
+template void MemFunTmpl::exportedStatic<ExplicitInst_Exported>();
+
+
+// Export specialization of an exported member function template.
+// M32-DAG: define dso_local dllexport x86_thiscallcc void @"??$exportedNormal@UExplicitSpec_Def_Exported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl* %this)
+// M64-DAG: define dso_local dllexport void @"??$exportedNormal@UExplicitSpec_Def_Exported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl* %this)
+// G32-DAG: define dso_local dllexport x86_thiscallcc void @_ZN10MemFunTmpl14exportedNormalI25ExplicitSpec_Def_ExportedEEvv(%struct.MemFunTmpl* %this)
+// G64-DAG: define dso_local dllexport void @_ZN10MemFunTmpl14exportedNormalI25ExplicitSpec_Def_ExportedEEvv(%struct.MemFunTmpl* %this)
+template<> __declspec(dllexport) void MemFunTmpl::exportedNormal<ExplicitSpec_Def_Exported>() {}
+
+// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"??$exportedNormal@UExplicitSpec_InlineDef_Exported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl* %this)
+// M64-DAG: define weak_odr dso_local dllexport void @"??$exportedNormal@UExplicitSpec_InlineDef_Exported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl* %this)
+// G32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @_ZN10MemFunTmpl14exportedNormalI31ExplicitSpec_InlineDef_ExportedEEvv(%struct.MemFunTmpl* %this)
+// G64-DAG: define weak_odr dso_local dllexport void @_ZN10MemFunTmpl14exportedNormalI31ExplicitSpec_InlineDef_ExportedEEvv(%struct.MemFunTmpl* %this)
+template<> __declspec(dllexport) inline void MemFunTmpl::exportedNormal<ExplicitSpec_InlineDef_Exported>() {}
+
+// MSC-DAG: define dso_local dllexport void @"??$exportedStatic@UExplicitSpec_Def_Exported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: define dso_local dllexport void @_ZN10MemFunTmpl14exportedStaticI25ExplicitSpec_Def_ExportedEEvv()
+template<> __declspec(dllexport) void MemFunTmpl::exportedStatic<ExplicitSpec_Def_Exported>() {}
+
+// MSC-DAG: define weak_odr dso_local dllexport void @"??$exportedStatic@UExplicitSpec_InlineDef_Exported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: define weak_odr dso_local dllexport void @_ZN10MemFunTmpl14exportedStaticI31ExplicitSpec_InlineDef_ExportedEEvv()
+template<> __declspec(dllexport) inline void MemFunTmpl::exportedStatic<ExplicitSpec_InlineDef_Exported>() {}
+
+
+// Not exporting specialization of an exported member function template without
+// explicit dso_local dllexport.
+// M32-DAG: define dso_local x86_thiscallcc void @"??$exportedNormal@UExplicitSpec_NotExported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl* %this)
+// M64-DAG: define dso_local void @"??$exportedNormal@UExplicitSpec_NotExported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl* %this)
+// G32-DAG: define dso_local x86_thiscallcc void @_ZN10MemFunTmpl14exportedNormalI24ExplicitSpec_NotExportedEEvv(%struct.MemFunTmpl* %this)
+// G64-DAG: define dso_local void @_ZN10MemFunTmpl14exportedNormalI24ExplicitSpec_NotExportedEEvv(%struct.MemFunTmpl* %this)
+template<> void MemFunTmpl::exportedNormal<ExplicitSpec_NotExported>() {}
+
+// M32-DAG: define dso_local void @"??$exportedStatic@UExplicitSpec_NotExported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: define dso_local void @_ZN10MemFunTmpl14exportedStaticI24ExplicitSpec_NotExportedEEvv()
+template<> void MemFunTmpl::exportedStatic<ExplicitSpec_NotExported>() {}
+
+
+// Export explicit instantiation declaration of a non-exported member function
+// template.
+// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"??$normalDef@UExplicitDecl_Exported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl* %this)
+// M64-DAG: define weak_odr dso_local dllexport void @"??$normalDef@UExplicitDecl_Exported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl* %this)
+// G32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @_ZN10MemFunTmpl9normalDefI21ExplicitDecl_ExportedEEvv(%struct.MemFunTmpl* %this)
+// G64-DAG: define weak_odr dso_local dllexport void @_ZN10MemFunTmpl9normalDefI21ExplicitDecl_ExportedEEvv(%struct.MemFunTmpl* %this)
+extern template __declspec(dllexport) void MemFunTmpl::normalDef<ExplicitDecl_Exported>();
+ template __declspec(dllexport) void MemFunTmpl::normalDef<ExplicitDecl_Exported>();
+
+// M32-DAG: define weak_odr dso_local dllexport void @"??$staticDef@UExplicitDecl_Exported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: define weak_odr dso_local dllexport void @_ZN10MemFunTmpl9staticDefI21ExplicitDecl_ExportedEEvv()
+extern template __declspec(dllexport) void MemFunTmpl::staticDef<ExplicitDecl_Exported>();
+ template __declspec(dllexport) void MemFunTmpl::staticDef<ExplicitDecl_Exported>();
+
+
+// Export explicit instantiation definition of a non-exported member function
+// template.
+// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"??$normalDef@UExplicitInst_Exported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl* %this)
+// M64-DAG: define weak_odr dso_local dllexport void @"??$normalDef@UExplicitInst_Exported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl* %this)
+// G32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @_ZN10MemFunTmpl9normalDefI21ExplicitInst_ExportedEEvv(%struct.MemFunTmpl* %this)
+// G64-DAG: define weak_odr dso_local dllexport void @_ZN10MemFunTmpl9normalDefI21ExplicitInst_ExportedEEvv(%struct.MemFunTmpl* %this)
+template __declspec(dllexport) void MemFunTmpl::normalDef<ExplicitInst_Exported>();
+
+// MSC-DAG: define weak_odr dso_local dllexport void @"??$staticDef@UExplicitInst_Exported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: define weak_odr dso_local dllexport void @_ZN10MemFunTmpl9staticDefI21ExplicitInst_ExportedEEvv()
+template __declspec(dllexport) void MemFunTmpl::staticDef<ExplicitInst_Exported>();
+
+
+// Export specialization of a non-exported member function template.
+// M32-DAG: define dso_local dllexport x86_thiscallcc void @"??$normalDef@UExplicitSpec_Def_Exported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl* %this)
+// M64-DAG: define dso_local dllexport void @"??$normalDef@UExplicitSpec_Def_Exported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl* %this)
+// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"??$normalDef@UExplicitSpec_InlineDef_Exported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl* %this)
+// M64-DAG: define weak_odr dso_local dllexport void @"??$normalDef@UExplicitSpec_InlineDef_Exported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl* %this)
+// G32-DAG: define dso_local dllexport x86_thiscallcc void @_ZN10MemFunTmpl9normalDefI25ExplicitSpec_Def_ExportedEEvv(%struct.MemFunTmpl* %this)
+// G64-DAG: define dso_local dllexport void @_ZN10MemFunTmpl9normalDefI25ExplicitSpec_Def_ExportedEEvv(%struct.MemFunTmpl* %this)
+// G32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @_ZN10MemFunTmpl9normalDefI31ExplicitSpec_InlineDef_ExportedEEvv(%struct.MemFunTmpl* %this)
+// G64-DAG: define weak_odr dso_local dllexport void @_ZN10MemFunTmpl9normalDefI31ExplicitSpec_InlineDef_ExportedEEvv(%struct.MemFunTmpl* %this)
+template<> __declspec(dllexport) void MemFunTmpl::normalDef<ExplicitSpec_Def_Exported>() {}
+template<> __declspec(dllexport) inline void MemFunTmpl::normalDef<ExplicitSpec_InlineDef_Exported>() {}
+
+// MSC-DAG: define dso_local dllexport void @"??$staticDef@UExplicitSpec_Def_Exported@@@MemFunTmpl@@SAXXZ"()
+// MSC-DAG: define weak_odr dso_local dllexport void @"??$staticDef@UExplicitSpec_InlineDef_Exported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: define dso_local dllexport void @_ZN10MemFunTmpl9staticDefI25ExplicitSpec_Def_ExportedEEvv()
+// GNU-DAG: define weak_odr dso_local dllexport void @_ZN10MemFunTmpl9staticDefI31ExplicitSpec_InlineDef_ExportedEEvv()
+template<> __declspec(dllexport) void MemFunTmpl::staticDef<ExplicitSpec_Def_Exported>() {}
+template<> __declspec(dllexport) inline void MemFunTmpl::staticDef<ExplicitSpec_InlineDef_Exported>() {}
+
+
+
+struct MemVarTmpl {
+ template<typename T> static const int StaticVar = 1;
+ template<typename T> __declspec(dllexport) static const int ExportedStaticVar = 1;
+};
+template<typename T> const int MemVarTmpl::StaticVar;
+template<typename T> const int MemVarTmpl::ExportedStaticVar;
+
+// Export implicit instantiation of an exported member variable template.
+// MSC-DAG: @"??$ExportedStaticVar@UImplicitInst_Exported@@@MemVarTmpl@@2HB" = weak_odr dso_local dllexport constant i32 1, comdat, align 4
+// GNU-DAG: @_ZN10MemVarTmpl17ExportedStaticVarI21ImplicitInst_ExportedEE = weak_odr dso_local dllexport constant i32 1, comdat, align 4
+int useMemVarTmpl() { return MemVarTmpl::ExportedStaticVar<ImplicitInst_Exported>; }
+
+// Export explicit instantiation declaration of an exported member variable
+// template.
+// MSC-DAG: @"??$ExportedStaticVar@UExplicitDecl_Exported@@@MemVarTmpl@@2HB" = weak_odr dso_local dllexport constant i32 1, comdat, align 4
+// GNU-DAG: @_ZN10MemVarTmpl17ExportedStaticVarI21ExplicitDecl_ExportedEE = weak_odr dso_local dllexport constant i32 1, comdat, align 4
+extern template const int MemVarTmpl::ExportedStaticVar<ExplicitDecl_Exported>;
+ template const int MemVarTmpl::ExportedStaticVar<ExplicitDecl_Exported>;
+
+// Export explicit instantiation definition of an exported member variable
+// template.
+// MSC-DAG: @"??$ExportedStaticVar@UExplicitInst_Exported@@@MemVarTmpl@@2HB" = weak_odr dso_local dllexport constant i32 1, comdat, align 4
+// GNU-DAG: @_ZN10MemVarTmpl17ExportedStaticVarI21ExplicitInst_ExportedEE = weak_odr dso_local dllexport constant i32 1, comdat, align 4
+template const int MemVarTmpl::ExportedStaticVar<ExplicitInst_Exported>;
+
+// Export specialization of an exported member variable template.
+// MSC-DAG: @"??$ExportedStaticVar@UExplicitSpec_Def_Exported@@@MemVarTmpl@@2HB" = weak_odr dso_local dllexport constant i32 1, comdat, align 4
+// GNU-DAG: @_ZN10MemVarTmpl17ExportedStaticVarI25ExplicitSpec_Def_ExportedEE = dso_local dllexport constant i32 1, align 4
+template<> __declspec(dllexport) const int MemVarTmpl::ExportedStaticVar<ExplicitSpec_Def_Exported> = 1;
+
+// Not exporting specialization of an exported member variable template without
+// explicit dllexport.
+// MSC-DAG: @"??$ExportedStaticVar@UExplicitSpec_NotExported@@@MemVarTmpl@@2HB" = weak_odr dso_local constant i32 1, comdat, align 4
+// GNU-DAG: @_ZN10MemVarTmpl17ExportedStaticVarI24ExplicitSpec_NotExportedEE = dso_local constant i32 1, align 4
+template<> const int MemVarTmpl::ExportedStaticVar<ExplicitSpec_NotExported> = 1;
+
+
+// Export explicit instantiation declaration of a non-exported member variable
+// template.
+// MSC-DAG: @"??$StaticVar@UExplicitDecl_Exported@@@MemVarTmpl@@2HB" = weak_odr dso_local dllexport constant i32 1, comdat, align 4
+// GNU-DAG: @_ZN10MemVarTmpl9StaticVarI21ExplicitDecl_ExportedEE = weak_odr dso_local dllexport constant i32 1, comdat, align 4
+extern template __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitDecl_Exported>;
+ template __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitDecl_Exported>;
+
+// Export explicit instantiation definition of a non-exported member variable
+// template.
+// MSC-DAG: @"??$StaticVar@UExplicitInst_Exported@@@MemVarTmpl@@2HB" = weak_odr dso_local dllexport constant i32 1, comdat, align 4
+// GNU-DAG: @_ZN10MemVarTmpl9StaticVarI21ExplicitInst_ExportedEE = weak_odr dso_local dllexport constant i32 1, comdat, align 4
+template __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitInst_Exported>;
+
+// Export specialization of a non-exported member variable template.
+// MSC-DAG: @"??$StaticVar@UExplicitSpec_Def_Exported@@@MemVarTmpl@@2HB" = weak_odr dso_local dllexport constant i32 1, comdat, align 4
+// GNU-DAG: @_ZN10MemVarTmpl9StaticVarI25ExplicitSpec_Def_ExportedEE = dso_local dllexport constant i32 1, align 4
+template<> __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitSpec_Def_Exported> = 1;
diff --git a/src/llvm-project/clang/test/CodeGenCXX/dllexport-missing-key.cpp b/src/llvm-project/clang/test/CodeGenCXX/dllexport-missing-key.cpp
new file mode 100644
index 0000000..90e736f
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/dllexport-missing-key.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -triple x86_64-windows-gnu -emit-llvm -std=c++11 -o - %s | FileCheck --check-prefix=GNU %s
+
+class __declspec(dllexport) QAbstractLayoutStyleInfo {
+public:
+ QAbstractLayoutStyleInfo() : m_isWindow(false) {}
+ virtual ~QAbstractLayoutStyleInfo() {}
+
+ virtual bool hasChangedCore() const { return false; }
+
+ virtual void invalidate() {}
+
+ virtual double windowMargin(bool orientation) const = 0;
+
+ bool isWindow() const { return m_isWindow; }
+
+protected:
+ bool m_isWindow;
+};
+
+// GNU-DAG: @_ZTV24QAbstractLayoutStyleInfo = weak_odr dso_local dllexport
+// GNU-DAG: @_ZTS24QAbstractLayoutStyleInfo = linkonce_odr
+// GNU-DAG: @_ZTI24QAbstractLayoutStyleInfo = linkonce_odr
diff --git a/src/llvm-project/clang/test/CodeGenCXX/dllexport-ms-friend.cpp b/src/llvm-project/clang/test/CodeGenCXX/dllexport-ms-friend.cpp
new file mode 100644
index 0000000..6702647
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/dllexport-ms-friend.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -triple %ms_abi_triple -fms-extensions -emit-llvm -O0 -o - %s | FileCheck %s
+
+// Friend functions defined in classes are emitted.
+// CHECK: define weak_odr dso_local dllexport void @"?friend1@@YAXXZ"()
+struct FuncFriend1 {
+ friend __declspec(dllexport) void friend1() {}
+};
+
+// But function templates and functions defined in class templates are not
+// emitted.
+// CHECK-NOT: friend2
+// CHECK-NOT: friend3
+// CHECK-NOT: friend4
+struct FuncFriend2 {
+ template<typename> friend __declspec(dllexport) void friend2() {}
+};
+template<typename> struct FuncFriend3 {
+ friend __declspec(dllexport) void friend3() {}
+ struct Inner {
+ friend __declspec(dllexport) void friend4() {}
+ };
+};
diff --git a/src/llvm-project/clang/test/CodeGenCXX/dllexport-no-dllexport-inlines.cpp b/src/llvm-project/clang/test/CodeGenCXX/dllexport-no-dllexport-inlines.cpp
new file mode 100644
index 0000000..3866731
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/dllexport-no-dllexport-inlines.cpp
@@ -0,0 +1,133 @@
+// RUN: %clang_cc1 %s -fms-extensions -triple x86_64-windows-msvc \
+// RUN: -disable-llvm-passes \
+// RUN: -fno-dllexport-inlines -emit-llvm -O1 -o - | \
+// RUN: FileCheck --check-prefix=CHECK --check-prefix=NOEXPORTINLINE %s
+
+// RUN: %clang_cc1 %s -fms-extensions -triple x86_64-windows-msvc \
+// RUN: -disable-llvm-passes \
+// RUN: -emit-llvm -O1 -o - | \
+// RUN: FileCheck --check-prefix=CHECK --check-prefix=EXPORTINLINE %s
+
+
+struct __declspec(dllexport) ExportedClass {
+
+ // NOEXPORTINLINE-DAG: define linkonce_odr dso_local void @"?InclassDefFunc@ExportedClass@@
+ // EXPORTINLINE-DAG: define weak_odr dso_local dllexport void @"?InclassDefFunc@ExportedClass@@
+ void InclassDefFunc() {}
+
+ // CHECK-DAG: define weak_odr dso_local dllexport i32 @"?InclassDefFuncWithStaticVariable@ExportedClass@@QEAAHXZ"
+ int InclassDefFuncWithStaticVariable() {
+ // CHECK-DAG: @"?static_variable@?1??InclassDefFuncWithStaticVariable@ExportedClass@@QEAAHXZ@4HA" = weak_odr dso_local dllexport global i32 0, comdat, align 4
+ static int static_variable = 0;
+ ++static_variable;
+ return static_variable;
+ }
+
+ // CHECK-DAG: define weak_odr dso_local dllexport i32 @"?InclassDefFunctWithLambdaStaticVariable@ExportedClass@@QEAAHXZ"
+ int InclassDefFunctWithLambdaStaticVariable() {
+ // CHECK-DAG: @"?static_x@?2???R<lambda_1>@?0??InclassDefFunctWithLambdaStaticVariable@ExportedClass@@QEAAHXZ@QEBA?A?<auto>@@XZ@4HA" = weak_odr dso_local dllexport global i32 0, comdat, align 4
+ return ([]() { static int static_x; return ++static_x; })();
+ }
+
+ // NOEXPORTINLINE-DAG: define linkonce_odr dso_local void @"?InlineOutclassDefFunc@ExportedClass@@QEAAXXZ
+ // EXPORTINLINE-DAG: define weak_odr dso_local dllexport void @"?InlineOutclassDefFunc@ExportedClass@@QEAAXXZ
+ inline void InlineOutclassDefFunc();
+
+ // CHECK-DAG: define weak_odr dso_local dllexport i32 @"?InlineOutclassDefFuncWithStaticVariable@ExportedClass@@QEAAHXZ"
+ inline int InlineOutclassDefFuncWithStaticVariable();
+
+ // CHECK-DAG: define dso_local dllexport void @"?OutoflineDefFunc@ExportedClass@@QEAAXXZ"
+ void OutoflineDefFunc();
+};
+
+void ExportedClass::OutoflineDefFunc() {}
+
+inline void ExportedClass::InlineOutclassDefFunc() {}
+
+inline int ExportedClass::InlineOutclassDefFuncWithStaticVariable() {
+ static int static_variable = 0;
+ return ++static_variable;
+}
+
+void ExportedClassUser() {
+ ExportedClass a;
+ a.InclassDefFunc();
+ a.InlineOutclassDefFunc();
+}
+
+template<typename T>
+struct __declspec(dllexport) TemplateExportedClass {
+ void InclassDefFunc() {}
+
+ int InclassDefFuncWithStaticVariable() {
+ static int static_x = 0;
+ return ++static_x;
+ }
+};
+
+class A11{};
+class B22{};
+
+// CHECK-DAG: define weak_odr dso_local dllexport void @"?InclassDefFunc@?$TemplateExportedClass@VA11@@@@QEAAXXZ"
+// CHECK-DAG: define weak_odr dso_local dllexport i32 @"?InclassDefFuncWithStaticVariable@?$TemplateExportedClass@VA11@@@@QEAAHXZ"
+// CHECK-DAG: @"?static_x@?2??InclassDefFuncWithStaticVariable@?$TemplateExportedClass@VA11@@@@QEAAHXZ@4HA" = weak_odr dso_local dllexport global i32 0, comdat, align 4
+template class TemplateExportedClass<A11>;
+
+// NOEXPORTINLINE-DAG: define linkonce_odr dso_local void @"?InclassDefFunc@?$TemplateExportedClass@VB22@@@@QEAAXXZ"
+// EXPORTINLINE-DAG: define weak_odr dso_local dllexport void @"?InclassDefFunc@?$TemplateExportedClass@VB22@@@@QEAAXXZ
+// CHECK-DAG: define weak_odr dso_local dllexport i32 @"?InclassDefFuncWithStaticVariable@?$TemplateExportedClass@VB22@@@@QEAAHXZ"
+// CHECK-DAG: @"?static_x@?2??InclassDefFuncWithStaticVariable@?$TemplateExportedClass@VB22@@@@QEAAHXZ@4HA" = weak_odr dso_local dllexport global i32 0, comdat, align 4
+TemplateExportedClass<B22> b22;
+
+void TemplateExportedClassUser() {
+ b22.InclassDefFunc();
+ b22.InclassDefFuncWithStaticVariable();
+}
+
+
+template<typename T>
+struct TemplateNoAttributeClass {
+ void InclassDefFunc() {}
+ int InclassDefFuncWithStaticLocal() {
+ static int static_x;
+ return ++static_x;
+ }
+};
+
+// CHECK-DAG: define weak_odr dso_local dllexport void @"?InclassDefFunc@?$TemplateNoAttributeClass@VA11@@@@QEAAXXZ"
+// CHECK-DAG: define weak_odr dso_local dllexport i32 @"?InclassDefFuncWithStaticLocal@?$TemplateNoAttributeClass@VA11
+// CHECK-DAG: @"?static_x@?2??InclassDefFuncWithStaticLocal@?$TemplateNoAttributeClass@VA11@@@@QEAAHXZ@4HA" = weak_odr dso_local dllexport global i32 0, comdat, align 4
+template class __declspec(dllexport) TemplateNoAttributeClass<A11>;
+
+// CHECK-DAG: define available_externally dllimport void @"?InclassDefFunc@?$TemplateNoAttributeClass@VB22@@@@QEAAXXZ"
+// CHECK-DAG: define available_externally dllimport i32 @"?InclassDefFuncWithStaticLocal@?$TemplateNoAttributeClass@VB22@@@@QEAAHXZ"
+// CHECK-DAG: @"?static_x@?2??InclassDefFuncWithStaticLocal@?$TemplateNoAttributeClass@VB22@@@@QEAAHXZ@4HA" = available_externally dllimport global i32 0, align 4
+extern template class __declspec(dllimport) TemplateNoAttributeClass<B22>;
+
+void TemplateNoAttributeClassUser() {
+ TemplateNoAttributeClass<B22> b22;
+ b22.InclassDefFunc();
+ b22.InclassDefFuncWithStaticLocal();
+}
+
+struct __declspec(dllimport) ImportedClass {
+ // NOEXPORTINLINE-DAG: define linkonce_odr dso_local void @"?InClassDefFunc@ImportedClass@@QEAAXXZ"
+ // EXPORTINLINE-DAG: define available_externally dllimport void @"?InClassDefFunc@ImportedClass@@QEAAXXZ"
+ void InClassDefFunc() {}
+
+ // EXPORTINLINE-DAG: define available_externally dllimport i32 @"?InClassDefFuncWithStaticVariable@ImportedClass@@QEAAHXZ"
+ // NOEXPORTINLINE-DAG: define linkonce_odr dso_local i32 @"?InClassDefFuncWithStaticVariable@ImportedClass@@QEAAHXZ"
+ int InClassDefFuncWithStaticVariable() {
+ // CHECK-DAG: @"?static_variable@?1??InClassDefFuncWithStaticVariable@ImportedClass@@QEAAHXZ@4HA" = available_externally dllimport global i32 0, align 4
+ static int static_variable = 0;
+ ++static_variable;
+ return static_variable;
+ }
+};
+
+int InClassDefFuncUser() {
+ // This is necessary for declare statement of ImportedClass::InClassDefFunc().
+ ImportedClass c;
+ c.InClassDefFunc();
+ return c.InClassDefFuncWithStaticVariable();
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/dllexport-pr26549.cpp b/src/llvm-project/clang/test/CodeGenCXX/dllexport-pr26549.cpp
new file mode 100644
index 0000000..c5ac1c1
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/dllexport-pr26549.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s -fms-extensions -triple x86_64-windows-msvc -emit-llvm -o - | FileCheck %s
+
+template <typename> struct MessageT { };
+extern template struct MessageT<int>;
+
+// CHECK: define weak_odr dso_local dllexport {{.*}} %struct.MessageT* @"??4?$MessageT@H@@QEAAAEAU0@AEBU0@@Z"(
+template struct __declspec(dllexport) MessageT<int>;
+// Previously we crashed when this dllexport was the last thing in the file.
+// DO NOT ADD MORE TESTS AFTER THIS LINE!
diff --git a/src/llvm-project/clang/test/CodeGenCXX/dllexport-vtable-thunks.cpp b/src/llvm-project/clang/test/CodeGenCXX/dllexport-vtable-thunks.cpp
new file mode 100644
index 0000000..5294784
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/dllexport-vtable-thunks.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple x86_64-windows-gnu -fdeclspec -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-windows-itanium -fdeclspec -emit-llvm -o - %s | FileCheck %s
+
+struct __declspec(dllexport) A {
+ virtual void m();
+};
+struct __declspec(dllexport) B {
+ virtual void m();
+};
+struct __declspec(dllexport) C : A, B {
+ virtual void m();
+};
+void C::m() {}
+// CHECK: define dso_local dllexport void @_ZThn8_N1C1mEv
+
+struct Base {
+ virtual void m();
+};
+struct __declspec(dllexport) Derived : virtual Base {
+ virtual void m();
+};
+void Derived::m() {}
+// CHECK: define dso_local dllexport void @_ZTv0_n24_N7Derived1mEv
diff --git a/src/llvm-project/clang/test/CodeGenCXX/dllexport.cpp b/src/llvm-project/clang/test/CodeGenCXX/dllexport.cpp
new file mode 100644
index 0000000..16cfb84
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/dllexport.cpp
@@ -0,0 +1,1035 @@
+// RUN: %clang_cc1 -triple i686-windows-msvc -emit-llvm -std=c++1y -fno-threadsafe-statics -fms-extensions -O1 -mconstructor-aliases -disable-llvm-passes -o - %s -w -fms-compatibility-version=19.00 | FileCheck -allow-deprecated-dag-overlap --check-prefix=MSC --check-prefix=M32 -check-prefix=MSVC2015 -check-prefix=M32MSVC2015 %s
+// RUN: %clang_cc1 -triple i686-windows-msvc -emit-llvm -std=c++1y -fno-threadsafe-statics -fms-extensions -O1 -mconstructor-aliases -disable-llvm-passes -o - %s -w -fms-compatibility-version=18.00 | FileCheck -allow-deprecated-dag-overlap --check-prefix=MSC --check-prefix=M32 -check-prefix=MSVC2013 -check-prefix=M32MSVC2013 %s
+
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c++1y -fno-threadsafe-statics -fms-extensions -O0 -o - %s -w -fms-compatibility-version=19.00 | FileCheck -allow-deprecated-dag-overlap --check-prefix=MSC --check-prefix=M64 -check-prefix=MSVC2015 -check-prefix=M64MSVC2015 %s
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c++1y -fno-threadsafe-statics -fms-extensions -O0 -o - %s -w -fms-compatibility-version=18.00 | FileCheck -allow-deprecated-dag-overlap --check-prefix=MSC --check-prefix=M64 -check-prefix=MSVC2013 -check-prefix=M64MSVC2013 %s
+
+// RUN: %clang_cc1 -triple i686-windows-gnu -emit-llvm -std=c++1y -fno-threadsafe-statics -fms-extensions -O0 -o - %s -w | FileCheck -allow-deprecated-dag-overlap --check-prefix=GNU --check-prefix=G32 %s
+// RUN: %clang_cc1 -triple x86_64-windows-gnu -emit-llvm -std=c++1y -fno-threadsafe-statics -fms-extensions -O0 -o - %s -w | FileCheck -allow-deprecated-dag-overlap --check-prefix=GNU --check-prefix=G64 %s
+
+// Helper structs to make templates more expressive.
+struct ImplicitInst_Exported {};
+struct ExplicitDecl_Exported {};
+struct ExplicitInst_Exported {};
+struct ExplicitSpec_Exported {};
+struct ExplicitSpec_Def_Exported {};
+struct ExplicitSpec_InlineDef_Exported {};
+struct ExplicitSpec_NotExported {};
+struct External { int v; };
+
+#define JOIN2(x, y) x##y
+#define JOIN(x, y) JOIN2(x, y)
+#define UNIQ(name) JOIN(name, __LINE__)
+#define USEVAR(var) int UNIQ(use)() { return var; }
+#define USE(func) void UNIQ(use)() { func(); }
+#define USEMEMFUNC(class, func) void (class::*UNIQ(use)())() { return &class::func; }
+#define INSTVAR(var) template int var;
+#define INST(func) template void func();
+
+// The vftable for struct W is comdat largest because we have RTTI.
+// M32-DAG: $"??_7W@@6B@" = comdat largest
+
+// M32-DAG: $"?smember@?$Base@H@PR32992@@0HA" = comdat any
+
+
+//===----------------------------------------------------------------------===//
+// Globals
+//===----------------------------------------------------------------------===//
+
+// Declarations are not exported.
+// MSC-NOT: @"?ExternGlobalDecl@@3HA"
+// GNU-NOT: @ExternGlobalDecl
+__declspec(dllexport) extern int ExternGlobalDecl;
+
+// M64-DAG: @__ImageBase = external dso_local constant i8
+
+// GNU-DAG: @_ZTVN10__cxxabiv117__class_type_infoE = external global
+
+// dllexport implies a definition.
+// MSC-DAG: @"?GlobalDef@@3HA" = dso_local dllexport global i32 0, align 4
+// GNU-DAG: @GlobalDef = dso_local dllexport global i32 0, align 4
+__declspec(dllexport) int GlobalDef;
+
+// Export definition.
+// MSC-DAG: @"?GlobalInit1@@3HA" = dso_local dllexport global i32 1, align 4
+// GNU-DAG: @GlobalInit1 = dso_local dllexport global i32 1, align 4
+__declspec(dllexport) int GlobalInit1 = 1;
+
+// MSC-DAG: @"?GlobalInit2@@3HA" = dso_local dllexport global i32 1, align 4
+// GNU-DAG: @GlobalInit2 = dso_local dllexport global i32 1, align 4
+int __declspec(dllexport) GlobalInit2 = 1;
+
+// Declare, then export definition.
+// MSC-DAG: @"?GlobalDeclInit@@3HA" = dso_local dllexport global i32 1, align 4
+// GNU-DAG: @GlobalDeclInit = dso_local dllexport global i32 1, align 4
+__declspec(dllexport) extern int GlobalDeclInit;
+int GlobalDeclInit = 1;
+
+// Redeclarations
+// MSC-DAG: @"?GlobalRedecl1@@3HA" = dso_local dllexport global i32 0, align 4
+// GNU-DAG: @GlobalRedecl1 = dso_local dllexport global i32 0, align 4
+__declspec(dllexport) extern int GlobalRedecl1;
+__declspec(dllexport) int GlobalRedecl1;
+
+// MSC-DAG: @"?GlobalRedecl2@@3HA" = dso_local dllexport global i32 0, align 4
+// GNU-DAG: @GlobalRedecl2 = dso_local dllexport global i32 0, align 4
+__declspec(dllexport) extern int GlobalRedecl2;
+ int GlobalRedecl2;
+
+// MSC-DAG: @"?ExternalGlobal@ns@@3HA" = dso_local dllexport global i32 0, align 4
+// GNU-DAG: @_ZN2ns14ExternalGlobalE = dso_local dllexport global i32 0, align 4
+namespace ns { __declspec(dllexport) int ExternalGlobal; }
+
+// MSC-DAG: @"?ExternalAutoTypeGlobal@@3UExternal@@A" = dso_local dllexport global %struct.External zeroinitializer, align 4
+// GNU-DAG: @ExternalAutoTypeGlobal = dso_local dllexport global %struct.External zeroinitializer, align 4
+__declspec(dllexport) auto ExternalAutoTypeGlobal = External();
+
+int f();
+// MSC-DAG: @"?x@?1??nonInlineStaticLocalsFunc@@YAHXZ@4HA" = internal {{(unnamed_addr )*}}global i32 0
+// MSC-DAG: @"?$S1@?1??nonInlineStaticLocalsFunc@@YAHXZ@4IA" = internal {{(unnamed_addr )*}}global i32 0
+int __declspec(dllexport) nonInlineStaticLocalsFunc() {
+ static int x = f();
+ return x++;
+};
+
+// MSC-DAG: @"?x@?1??inlineStaticLocalsFunc@@YAHXZ@4HA" = weak_odr dso_local dllexport global i32 0, comdat
+// MSC-DAG: @"??_B?1??inlineStaticLocalsFunc@@YAHXZ@51" = weak_odr dllexport global i32 0, comdat
+// Note: MinGW doesn't seem to export the static local here.
+inline int __declspec(dllexport) inlineStaticLocalsFunc() {
+ static int x = f();
+ return x++;
+}
+
+namespace PR32992 {
+// Static data members of a instantiated base class should be exported.
+template <class T>
+class Base {
+ virtual void myfunc() {}
+ static int smember;
+};
+// MSC-DAG: @"?smember@?$Base@H@PR32992@@0HA" = weak_odr dso_local dllexport global i32 77, comdat, align 4
+template <class T> int Base<T>::smember = 77;
+template <class T>
+class __declspec(dllexport) Derived2 : Base<T> {
+ void myfunc() {}
+};
+class Derived : public Derived2<int> {
+ void myfunc() {}
+};
+} // namespace PR32992
+
+namespace PR32992_1 {
+namespace a { enum b { c }; }
+template <typename> class d {
+ static constexpr a::b e = a::c;
+};
+namespace f {
+ template <typename g = int> class h : d<g> {};
+}
+using f::h;
+class __declspec(dllexport) i : h<> {};
+}
+
+//===----------------------------------------------------------------------===//
+// Variable templates
+//===----------------------------------------------------------------------===//
+
+// Declarations are not exported.
+
+// MSC-DAG: @"??$VarTmplImplicitDef@UImplicitInst_Exported@@@@3HA" = external dso_local global
+// GNU-DAG: @_Z18VarTmplImplicitDefI21ImplicitInst_ExportedE = external global
+template<typename T> __declspec(dllexport) extern int VarTmplImplicitDef;
+USEVAR(VarTmplImplicitDef<ImplicitInst_Exported>)
+
+// Export definition.
+// MSC-DAG: @"??$VarTmplInit1@UExplicitInst_Exported@@@@3HA" = weak_odr dso_local dllexport global i32 1, comdat, align 4
+// GNU-DAG: @_Z12VarTmplInit1I21ExplicitInst_ExportedE = weak_odr dso_local dllexport global i32 1, comdat, align 4
+template<typename T> __declspec(dllexport) int VarTmplInit1 = 1;
+INSTVAR(VarTmplInit1<ExplicitInst_Exported>)
+
+// MSC-DAG: @"??$VarTmplInit2@UExplicitInst_Exported@@@@3HA" = weak_odr dso_local dllexport global i32 1, comdat, align 4
+// GNU-DAG: @_Z12VarTmplInit2I21ExplicitInst_ExportedE = weak_odr dso_local dllexport global i32 1, comdat, align 4
+template<typename T> int __declspec(dllexport) VarTmplInit2 = 1;
+INSTVAR(VarTmplInit2<ExplicitInst_Exported>)
+
+// Declare, then export definition.
+// MSC-DAG: @"??$VarTmplDeclInit@UExplicitInst_Exported@@@@3HA" = weak_odr dso_local dllexport global i32 1, comdat, align 4
+// GNU-DAG: @_Z15VarTmplDeclInitI21ExplicitInst_ExportedE = weak_odr dso_local dllexport global i32 1, comdat, align 4
+template<typename T> __declspec(dllexport) extern int VarTmplDeclInit;
+template<typename T> int VarTmplDeclInit = 1;
+INSTVAR(VarTmplDeclInit<ExplicitInst_Exported>)
+
+// Redeclarations
+// MSC-DAG: @"??$VarTmplRedecl1@UExplicitInst_Exported@@@@3HA" = weak_odr dso_local dllexport global i32 1, comdat, align 4
+// GNU-DAG: @_Z14VarTmplRedecl1I21ExplicitInst_ExportedE = weak_odr dso_local dllexport global i32 1, comdat, align 4
+template<typename T> __declspec(dllexport) extern int VarTmplRedecl1;
+template<typename T> __declspec(dllexport) int VarTmplRedecl1 = 1;
+INSTVAR(VarTmplRedecl1<ExplicitInst_Exported>)
+
+// MSC-DAG: @"??$VarTmplRedecl2@UExplicitInst_Exported@@@@3HA" = weak_odr dso_local dllexport global i32 1, comdat, align 4
+// GNU-DAG: @_Z14VarTmplRedecl2I21ExplicitInst_ExportedE = weak_odr dso_local dllexport global i32 1, comdat, align 4
+template<typename T> __declspec(dllexport) extern int VarTmplRedecl2;
+template<typename T> int VarTmplRedecl2 = 1;
+INSTVAR(VarTmplRedecl2<ExplicitInst_Exported>)
+
+// MSC-DAG: @"??$ExternalVarTmpl@UExplicitInst_Exported@@@ns@@3HA" = weak_odr dso_local dllexport global i32 1, comdat, align 4
+// GNU-DAG: @_ZN2ns15ExternalVarTmplI21ExplicitInst_ExportedEE = weak_odr dso_local dllexport global i32 1, comdat, align 4
+namespace ns { template<typename T> __declspec(dllexport) int ExternalVarTmpl = 1; }
+INSTVAR(ns::ExternalVarTmpl<ExplicitInst_Exported>)
+
+// MSC-DAG: @"??$ExternalAutoTypeVarTmpl@UExplicitInst_Exported@@@@3UExternal@@A" = weak_odr dso_local dllexport global %struct.External zeroinitializer, comdat, align 4
+// GNU-DAG: @_Z23ExternalAutoTypeVarTmplI21ExplicitInst_ExportedE = weak_odr dso_local dllexport global %struct.External zeroinitializer, comdat, align 4
+template<typename T> __declspec(dllexport) auto ExternalAutoTypeVarTmpl = External();
+template External ExternalAutoTypeVarTmpl<ExplicitInst_Exported>;
+
+
+template<typename T> int VarTmpl = 1;
+template<typename T> __declspec(dllexport) int ExportedVarTmpl = 1;
+
+// Export implicit instantiation of an exported variable template.
+// MSC-DAG: @"??$ExportedVarTmpl@UImplicitInst_Exported@@@@3HA" = weak_odr dso_local dllexport global i32 1, comdat, align 4
+// GNU-DAG: @_Z15ExportedVarTmplI21ImplicitInst_ExportedE = weak_odr dso_local dllexport global i32 1, comdat, align 4
+USEVAR(ExportedVarTmpl<ImplicitInst_Exported>)
+
+// Export explicit instantiation declaration of an exported variable template.
+// MSC-DAG: @"??$ExportedVarTmpl@UImplicitInst_Exported@@@@3HA" = weak_odr dso_local dllexport global i32 1, comdat, align 4
+// GNU-DAG: @_Z15ExportedVarTmplI21ExplicitDecl_ExportedE = weak_odr dso_local dllexport global i32 1, comdat, align 4
+extern template int ExportedVarTmpl<ExplicitDecl_Exported>;
+ template int ExportedVarTmpl<ExplicitDecl_Exported>;
+
+// Export explicit instantiation definition of an exported variable template.
+// MSC-DAG: @"??$ExportedVarTmpl@UImplicitInst_Exported@@@@3HA" = weak_odr dso_local dllexport global i32 1, comdat, align 4
+// GNU-DAG: @_Z15ExportedVarTmplI21ExplicitInst_ExportedE = weak_odr dso_local dllexport global i32 1, comdat, align 4
+template __declspec(dllexport) int ExportedVarTmpl<ExplicitInst_Exported>;
+
+// Export specialization of an exported variable template.
+// MSC-DAG: @"??$ExportedVarTmpl@UExplicitSpec_Exported@@@@3HA" = dso_local dllexport global i32 0, align 4
+// GNU-DAG: @_Z15ExportedVarTmplI21ExplicitSpec_ExportedE = dso_local dllexport global i32 0, align 4
+template<> __declspec(dllexport) int ExportedVarTmpl<ExplicitSpec_Exported>;
+
+// MSC-DAG: @"??$ExportedVarTmpl@UExplicitSpec_Def_Exported@@@@3HA" = dso_local dllexport global i32 1, align 4
+// GNU-DAG: @_Z15ExportedVarTmplI25ExplicitSpec_Def_ExportedE = dso_local dllexport global i32 1, align 4
+template<> __declspec(dllexport) int ExportedVarTmpl<ExplicitSpec_Def_Exported> = 1;
+
+// Not exporting specialization of an exported variable template without
+// explicit dllexport.
+// MSC-DAG: @"??$ExportedVarTmpl@UExplicitSpec_NotExported@@@@3HA" = dso_local global i32 0, align 4
+// GNU-DAG: @_Z15ExportedVarTmplI24ExplicitSpec_NotExportedE = dso_local global i32 0, align 4
+template<> int ExportedVarTmpl<ExplicitSpec_NotExported>;
+
+
+// Export explicit instantiation declaration of a non-exported variable template.
+// MSC-DAG: @"??$VarTmpl@UExplicitDecl_Exported@@@@3HA" = weak_odr dso_local dllexport global i32 1, comdat, align 4
+// GNU-DAG: @_Z7VarTmplI21ExplicitDecl_ExportedE = weak_odr dso_local dllexport global i32 1, comdat, align 4
+extern template __declspec(dllexport) int VarTmpl<ExplicitDecl_Exported>;
+ template __declspec(dllexport) int VarTmpl<ExplicitDecl_Exported>;
+
+// Export explicit instantiation definition of a non-exported variable template.
+// MSC-DAG: @"??$VarTmpl@UExplicitInst_Exported@@@@3HA" = weak_odr dso_local dllexport global i32 1, comdat, align 4
+// GNU-DAG: @_Z7VarTmplI21ExplicitInst_ExportedE = weak_odr dso_local dllexport global i32 1, comdat, align 4
+template __declspec(dllexport) int VarTmpl<ExplicitInst_Exported>;
+
+// Export specialization of a non-exported variable template.
+// MSC-DAG: @"??$VarTmpl@UExplicitSpec_Exported@@@@3HA" = dso_local dllexport global i32 0, align 4
+// GNU-DAG: @_Z7VarTmplI21ExplicitSpec_ExportedE = dso_local dllexport global i32 0, align 4
+template<> __declspec(dllexport) int VarTmpl<ExplicitSpec_Exported>;
+
+// MSC-DAG: @"??$VarTmpl@UExplicitSpec_Def_Exported@@@@3HA" = dso_local dllexport global i32 1, align 4
+// GNU-DAG: @_Z7VarTmplI25ExplicitSpec_Def_ExportedE = dso_local dllexport global i32 1, align 4
+template<> __declspec(dllexport) int VarTmpl<ExplicitSpec_Def_Exported> = 1;
+
+
+
+//===----------------------------------------------------------------------===//
+// Functions
+//===----------------------------------------------------------------------===//
+
+// Declarations are not exported.
+
+// Export function definition.
+// MSC-DAG: define dso_local dllexport void @"?def@@YAXXZ"()
+// GNU-DAG: define dso_local dllexport void @_Z3defv()
+__declspec(dllexport) void def() {}
+
+// extern "C"
+// MSC-DAG: define dso_local dllexport void @externC()
+// GNU-DAG: define dso_local dllexport void @externC()
+extern "C" __declspec(dllexport) void externC() {}
+
+// Export inline function.
+// MSC-DAG: define weak_odr dso_local dllexport void @"?inlineFunc@@YAXXZ"()
+// GNU-DAG: define weak_odr dso_local dllexport void @_Z10inlineFuncv()
+__declspec(dllexport) inline void inlineFunc() {}
+
+// MSC-DAG: define weak_odr dso_local dllexport void @"?inlineDecl@@YAXXZ"()
+// GNU-DAG: define weak_odr dso_local dllexport void @_Z10inlineDeclv()
+__declspec(dllexport) inline void inlineDecl();
+ void inlineDecl() {}
+
+// MSC-DAG: define weak_odr dso_local dllexport void @"?inlineDef@@YAXXZ"()
+// GNU-DAG: define weak_odr dso_local dllexport void @_Z9inlineDefv()
+__declspec(dllexport) void inlineDef();
+ inline void inlineDef() {}
+
+// Redeclarations
+// MSC-DAG: define dso_local dllexport void @"?redecl1@@YAXXZ"()
+// GNU-DAG: define dso_local dllexport void @_Z7redecl1v()
+__declspec(dllexport) void redecl1();
+__declspec(dllexport) void redecl1() {}
+
+// MSC-DAG: define dso_local dllexport void @"?redecl2@@YAXXZ"()
+// GNU-DAG: define dso_local dllexport void @_Z7redecl2v()
+__declspec(dllexport) void redecl2();
+ void redecl2() {}
+
+// Friend functions
+// MSC-DAG: define dso_local dllexport void @"?friend1@@YAXXZ"()
+// GNU-DAG: define dso_local dllexport void @_Z7friend1v()
+// MSC-DAG: define dso_local dllexport void @"?friend2@@YAXXZ"()
+// GNU-DAG: define dso_local dllexport void @_Z7friend2v()
+struct FuncFriend {
+ friend __declspec(dllexport) void friend1();
+ friend __declspec(dllexport) void friend2();
+};
+__declspec(dllexport) void friend1() {}
+ void friend2() {}
+
+// MSC-DAG: define dso_local dllexport void @"?func@Befriended@@SAXXZ"()
+// GNU-DAG: define dso_local dllexport void @_ZN10Befriended4funcEv()
+struct __declspec(dllexport) Befriended {
+ static void func();
+ struct Befriending {
+ friend void Befriended::func();
+ };
+};
+void Befriended::func() {}
+
+// Implicit declarations can be redeclared with dllexport.
+// MSC-DAG: define dso_local dllexport noalias i8* @"??2@{{YAPAXI|YAPEAX_K}}@Z"(
+// GNU-DAG: define dso_local dllexport noalias i8* @_Znw{{[yj]}}(
+void* alloc(__SIZE_TYPE__ n);
+__declspec(dllexport) void* operator new(__SIZE_TYPE__ n) { return alloc(n); }
+
+// MSC-DAG: define dso_local dllexport void @"?externalFunc@ns@@YAXXZ"()
+// GNU-DAG: define dso_local dllexport void @_ZN2ns12externalFuncEv()
+namespace ns { __declspec(dllexport) void externalFunc() {} }
+
+
+
+//===----------------------------------------------------------------------===//
+// Function templates
+//===----------------------------------------------------------------------===//
+
+// Export function template definition.
+// MSC-DAG: define weak_odr dso_local dllexport void @"??$funcTmplDef@UExplicitInst_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dso_local dllexport void @_Z11funcTmplDefI21ExplicitInst_ExportedEvv()
+template<typename T> __declspec(dllexport) void funcTmplDef() {}
+INST(funcTmplDef<ExplicitInst_Exported>)
+
+// Export inline function template.
+// MSC-DAG: define weak_odr dso_local dllexport void @"??$inlineFuncTmpl1@UExplicitInst_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dso_local dllexport void @_Z15inlineFuncTmpl1I21ExplicitInst_ExportedEvv()
+template<typename T> __declspec(dllexport) inline void inlineFuncTmpl1() {}
+INST(inlineFuncTmpl1<ExplicitInst_Exported>)
+
+// MSC-DAG: define weak_odr dso_local dllexport void @"??$inlineFuncTmpl2@UExplicitInst_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dso_local dllexport void @_Z15inlineFuncTmpl2I21ExplicitInst_ExportedEvv()
+template<typename T> inline void __attribute__((dllexport)) inlineFuncTmpl2() {}
+INST(inlineFuncTmpl2<ExplicitInst_Exported>)
+
+// MSC-DAG: define weak_odr dso_local dllexport void @"??$inlineFuncTmplDecl@UExplicitInst_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dso_local dllexport void @_Z18inlineFuncTmplDeclI21ExplicitInst_ExportedEvv()
+template<typename T> __declspec(dllexport) inline void inlineFuncTmplDecl();
+template<typename T> void inlineFuncTmplDecl() {}
+INST(inlineFuncTmplDecl<ExplicitInst_Exported>)
+
+// MSC-DAG: define weak_odr dso_local dllexport void @"??$inlineFuncTmplDef@UExplicitInst_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dso_local dllexport void @_Z17inlineFuncTmplDefI21ExplicitInst_ExportedEvv()
+template<typename T> __declspec(dllexport) void inlineFuncTmplDef();
+template<typename T> inline void inlineFuncTmplDef() {}
+INST(inlineFuncTmplDef<ExplicitInst_Exported>)
+
+
+// Redeclarations
+// MSC-DAG: define weak_odr dso_local dllexport void @"??$funcTmplRedecl1@UExplicitInst_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dso_local dllexport void @_Z15funcTmplRedecl1I21ExplicitInst_ExportedEvv()
+template<typename T> __declspec(dllexport) void funcTmplRedecl1();
+template<typename T> __declspec(dllexport) void funcTmplRedecl1() {}
+INST(funcTmplRedecl1<ExplicitInst_Exported>)
+
+// MSC-DAG: define weak_odr dso_local dllexport void @"??$funcTmplRedecl2@UExplicitInst_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dso_local dllexport void @_Z15funcTmplRedecl2I21ExplicitInst_ExportedEvv()
+template<typename T> __declspec(dllexport) void funcTmplRedecl2();
+template<typename T> void funcTmplRedecl2() {}
+INST(funcTmplRedecl2<ExplicitInst_Exported>)
+
+// MSC-DAG: define weak_odr dso_local dllexport void @"??$funcTmplRedecl3@UExplicitInst_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dso_local dllexport void @_Z15funcTmplRedecl3I21ExplicitInst_ExportedEvv()
+template<typename T> __declspec(dllexport) void funcTmplRedecl3();
+template<typename T> void funcTmplRedecl3() {}
+INST(funcTmplRedecl3<ExplicitInst_Exported>)
+
+
+// Function template friends
+// MSC-DAG: define weak_odr dso_local dllexport void @"??$funcTmplFriend1@UExplicitInst_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dso_local dllexport void @_Z15funcTmplFriend1I21ExplicitInst_ExportedEvv()
+// MSC-DAG: define weak_odr dso_local dllexport void @"??$funcTmplFriend2@UExplicitInst_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dso_local dllexport void @_Z15funcTmplFriend2I21ExplicitInst_ExportedEvv()
+struct FuncTmplFriend {
+ template<typename T> friend __declspec(dllexport) void funcTmplFriend1();
+ template<typename T> friend __declspec(dllexport) void funcTmplFriend2();
+};
+template<typename T> __declspec(dllexport) void funcTmplFriend1() {}
+template<typename T> void funcTmplFriend2() {}
+INST(funcTmplFriend1<ExplicitInst_Exported>)
+INST(funcTmplFriend2<ExplicitInst_Exported>)
+
+// MSC-DAG: define weak_odr dso_local dllexport void @"??$externalFuncTmpl@UExplicitInst_Exported@@@ns@@YAXXZ"()
+// GNU-DAG: define weak_odr dso_local dllexport void @_ZN2ns16externalFuncTmplI21ExplicitInst_ExportedEEvv()
+namespace ns { template<typename T> __declspec(dllexport) void externalFuncTmpl() {} }
+INST(ns::externalFuncTmpl<ExplicitInst_Exported>)
+
+
+template<typename T> void funcTmpl() {}
+template<typename T> __declspec(dllexport) void exportedFuncTmpl() {}
+
+// Export implicit instantiation of an exported function template.
+// MSC-DAG: define weak_odr dso_local dllexport void @"??$exportedFuncTmpl@UImplicitInst_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dso_local dllexport void @_Z16exportedFuncTmplI21ImplicitInst_ExportedEvv()
+USE(exportedFuncTmpl<ImplicitInst_Exported>)
+
+// Export explicit instantiation declaration of an exported function template.
+// MSC-DAG: define weak_odr dso_local dllexport void @"??$exportedFuncTmpl@UExplicitDecl_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dso_local dllexport void @_Z16exportedFuncTmplI21ExplicitDecl_ExportedEvv()
+extern template void exportedFuncTmpl<ExplicitDecl_Exported>();
+ template void exportedFuncTmpl<ExplicitDecl_Exported>();
+
+// Export explicit instantiation definition of an exported function template.
+// MSC-DAG: define weak_odr dso_local dllexport void @"??$exportedFuncTmpl@UExplicitInst_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dso_local dllexport void @_Z16exportedFuncTmplI21ExplicitInst_ExportedEvv()
+template void exportedFuncTmpl<ExplicitInst_Exported>();
+
+// Export specialization of an exported function template.
+// MSC-DAG: define dso_local dllexport void @"??$exportedFuncTmpl@UExplicitSpec_Def_Exported@@@@YAXXZ"()
+// GNU-DAG: define dso_local dllexport void @_Z16exportedFuncTmplI25ExplicitSpec_Def_ExportedEvv()
+template<> __declspec(dllexport) void exportedFuncTmpl<ExplicitSpec_Def_Exported>() {}
+
+// MSC-DAG: define weak_odr dso_local dllexport void @"??$exportedFuncTmpl@UExplicitSpec_InlineDef_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dso_local dllexport void @_Z16exportedFuncTmplI31ExplicitSpec_InlineDef_ExportedEvv()
+template<> __declspec(dllexport) inline void exportedFuncTmpl<ExplicitSpec_InlineDef_Exported>() {}
+
+// Not exporting specialization of an exported function template without
+// explicit dllexport.
+// MSC-DAG: define dso_local void @"??$exportedFuncTmpl@UExplicitSpec_NotExported@@@@YAXXZ"()
+// GNU-DAG: define dso_local void @_Z16exportedFuncTmplI24ExplicitSpec_NotExportedEvv()
+template<> void exportedFuncTmpl<ExplicitSpec_NotExported>() {}
+
+
+// Export explicit instantiation declaration of a non-exported function template.
+// MSC-DAG: define weak_odr dso_local dllexport void @"??$funcTmpl@UExplicitDecl_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dso_local dllexport void @_Z8funcTmplI21ExplicitDecl_ExportedEvv()
+extern template __declspec(dllexport) void funcTmpl<ExplicitDecl_Exported>();
+ template __declspec(dllexport) void funcTmpl<ExplicitDecl_Exported>();
+
+// Export explicit instantiation definition of a non-exported function template.
+// MSC-DAG: define weak_odr dso_local dllexport void @"??$funcTmpl@UExplicitInst_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dso_local dllexport void @_Z8funcTmplI21ExplicitInst_ExportedEvv()
+template __declspec(dllexport) void funcTmpl<ExplicitInst_Exported>();
+
+// Export specialization of a non-exported function template.
+// MSC-DAG: define dso_local dllexport void @"??$funcTmpl@UExplicitSpec_Def_Exported@@@@YAXXZ"()
+// GNU-DAG: define dso_local dllexport void @_Z8funcTmplI25ExplicitSpec_Def_ExportedEvv()
+template<> __declspec(dllexport) void funcTmpl<ExplicitSpec_Def_Exported>() {}
+
+// MSC-DAG: define weak_odr dso_local dllexport void @"??$funcTmpl@UExplicitSpec_InlineDef_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dso_local dllexport void @_Z8funcTmplI31ExplicitSpec_InlineDef_ExportedEvv()
+template<> __declspec(dllexport) inline void funcTmpl<ExplicitSpec_InlineDef_Exported>() {}
+
+
+
+//===----------------------------------------------------------------------===//
+// Precedence
+//===----------------------------------------------------------------------===//
+
+// dllexport takes precedence over the dllimport if both are specified.
+// MSC-DAG: @"?PrecedenceGlobal1A@@3HA" = dso_local dllexport global i32 0, align 4
+// MSC-DAG: @"?PrecedenceGlobal1B@@3HA" = dso_local dllexport global i32 0, align 4
+// GNU-DAG: @PrecedenceGlobal1A = dso_local dllexport global i32 0, align 4
+// GNU-DAG: @PrecedenceGlobal1B = dso_local dllexport global i32 0, align 4
+__attribute__((dllimport, dllexport)) int PrecedenceGlobal1A; // dllimport ignored
+__declspec(dllimport) __declspec(dllexport) int PrecedenceGlobal1B; // dllimport ignored
+
+// MSC-DAG: @"?PrecedenceGlobal2A@@3HA" = dso_local dllexport global i32 0, align 4
+// MSC-DAG: @"?PrecedenceGlobal2B@@3HA" = dso_local dllexport global i32 0, align 4
+// GNU-DAG: @PrecedenceGlobal2A = dso_local dllexport global i32 0, align 4
+// GNU-DAG: @PrecedenceGlobal2B = dso_local dllexport global i32 0, align 4
+__attribute__((dllexport, dllimport)) int PrecedenceGlobal2A; // dllimport ignored
+__declspec(dllexport) __declspec(dllimport) int PrecedenceGlobal2B; // dllimport ignored
+
+// MSC-DAG: @"?PrecedenceGlobalRedecl1@@3HA" = dso_local dllexport global i32 0, align 4
+// GNU-DAG: @PrecedenceGlobalRedecl1 = dso_local dllexport global i32 0, align 4
+__declspec(dllexport) extern int PrecedenceGlobalRedecl1;
+__declspec(dllimport) int PrecedenceGlobalRedecl1 = 0;
+
+// MSC-DAG: @"?PrecedenceGlobalRedecl2@@3HA" = dso_local dllexport global i32 0, align 4
+// GNU-DAG: @PrecedenceGlobalRedecl2 = dso_local dllexport global i32 0, align 4
+__declspec(dllimport) extern int PrecedenceGlobalRedecl2;
+__declspec(dllexport) int PrecedenceGlobalRedecl2;
+
+// MSC-DAG: @"?PrecedenceGlobalMixed1@@3HA" = dso_local dllexport global i32 0, align 4
+// GNU-DAG: @PrecedenceGlobalMixed1 = dso_local dllexport global i32 0, align 4
+__attribute__((dllexport)) extern int PrecedenceGlobalMixed1;
+__declspec(dllimport) int PrecedenceGlobalMixed1 = 0;
+
+// MSC-DAG: @"?PrecedenceGlobalMixed2@@3HA" = dso_local dllexport global i32 0, align 4
+// GNU-DAG: @PrecedenceGlobalMixed2 = dso_local dllexport global i32 0, align 4
+__attribute__((dllimport)) extern int PrecedenceGlobalMixed2;
+__declspec(dllexport) int PrecedenceGlobalMixed2;
+
+// MSC-DAG: define dso_local dllexport void @"?precedence1A@@YAXXZ"
+// MSC-DAG: define dso_local dllexport void @"?precedence1B@@YAXXZ"
+// GNU-DAG: define dso_local dllexport void @_Z12precedence1Av()
+// GNU-DAG: define dso_local dllexport void @_Z12precedence1Bv()
+void __attribute__((dllimport, dllexport)) precedence1A() {}
+void __declspec(dllimport) __declspec(dllexport) precedence1B() {}
+
+// MSC-DAG: define dso_local dllexport void @"?precedence2A@@YAXXZ"
+// MSC-DAG: define dso_local dllexport void @"?precedence2B@@YAXXZ"
+// GNU-DAG: define dso_local dllexport void @_Z12precedence2Av()
+// GNU-DAG: define dso_local dllexport void @_Z12precedence2Bv()
+void __attribute__((dllexport, dllimport)) precedence2A() {}
+void __declspec(dllexport) __declspec(dllimport) precedence2B() {}
+
+// MSC-DAG: define dso_local dllexport void @"?precedenceRedecl1@@YAXXZ"
+// GNU-DAG: define dso_local dllexport void @_Z17precedenceRedecl1v()
+void __declspec(dllimport) precedenceRedecl1();
+void __declspec(dllexport) precedenceRedecl1() {}
+
+// MSC-DAG: define dso_local dllexport void @"?precedenceRedecl2@@YAXXZ"
+// GNU-DAG: define dso_local dllexport void @_Z17precedenceRedecl2v()
+void __declspec(dllexport) precedenceRedecl2();
+void __declspec(dllimport) precedenceRedecl2() {}
+
+
+
+//===----------------------------------------------------------------------===//
+// Classes
+//===----------------------------------------------------------------------===//
+
+struct S {
+ void __declspec(dllexport) a() {}
+ // M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?a@S@@QAEXXZ"
+
+ struct T {
+ void __declspec(dllexport) a() {}
+ // M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?a@T@S@@QAEXXZ"
+ };
+};
+
+template <typename T>
+struct SomeTemplate {
+ SomeTemplate(T o = T()) : o(o) {}
+ T o;
+};
+// MSVC2015-DAG: define weak_odr dso_local dllexport {{.+}} @"??4?$SomeTemplate@H@@Q{{.+}}@$$Q{{.+}}@@Z"
+// MSVC2013-DAG: define weak_odr dso_local dllexport {{.+}} @"??4?$SomeTemplate@H@@Q{{.+}}0@A{{.+}}0@@Z"
+struct __declspec(dllexport) InheritFromTemplate : SomeTemplate<int> {};
+
+// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"??_F?$SomeTemplate@H@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat
+
+namespace PR23801 {
+template <typename>
+struct S {
+ ~S() {}
+};
+struct A {
+ A(int);
+ S<int> s;
+};
+struct __declspec(dllexport) B {
+ B(A = 0) {}
+};
+
+}
+//
+// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"??_FB@PR23801@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat
+
+struct __declspec(dllexport) T {
+ // Copy assignment operator:
+ // M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.T* @"??4T@@QAEAAU0@ABU0@@Z"
+
+ // Explicitly defaulted copy constructur:
+ T(const T&) = default;
+ // M32MSVC2013-DAG: define weak_odr dso_local dllexport x86_thiscallcc %struct.T* @"??0T@@QAE@ABU0@@Z"
+
+ void a() {}
+ // M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?a@T@@QAEXXZ"
+
+ static int b;
+ // M32-DAG: @"?b@T@@2HA" = external dso_local global i32
+
+ static int c;
+ // M32-DAG: @"?c@T@@2HA" = dso_local dllexport global i32 0, align 4
+};
+
+USEVAR(T::b)
+int T::c;
+
+// Export template class with static member variable
+// MSC-DAG: @"?StaticClassVarExpTmplClass@?$TmplClass@H@@2HA" = weak_odr dso_local dllexport global i32 0, comdat, align 4
+// GNU-DAG: @_ZN9TmplClassIiE26StaticClassVarExpTmplClassE = weak_odr dso_local dllexport global i32 0, comdat, align 4
+template<typename T>
+struct __declspec(dllexport) TmplClass
+{
+ static T StaticClassVarExpTmplClass;
+};
+
+template<typename T>
+T TmplClass<T>::StaticClassVarExpTmplClass;
+
+// Export a definition of a template function.
+// MSC-DAG: define weak_odr dso_local dllexport i32 @"??$TypeFunTmpl@H@@YAHH@Z"
+// GNU-DAG: define weak_odr dso_local dllexport i32 @_Z11TypeFunTmplIiET_S0_
+template<typename T>
+T __declspec(dllexport) TypeFunTmpl(T t) { return t + t; }
+
+// Instantiate the exported template class and the exported template function.
+int useExportedTmplStaticAndFun()
+{
+ return TmplClass<int>::StaticClassVarExpTmplClass + TypeFunTmpl<int>(10);
+}
+
+template <typename T> struct __declspec(dllexport) U { void foo() {} };
+struct __declspec(dllexport) V : public U<int> { };
+// U<int>'s assignment operator is emitted.
+// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.U* @"??4?$U@H@@QAEAAU0@ABU0@@Z"
+
+struct __declspec(dllexport) W { virtual void foo(); };
+void W::foo() {}
+// Default ctor:
+// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc %struct.W* @"??0W@@QAE@XZ"
+// Copy ctor:
+// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc %struct.W* @"??0W@@QAE@ABU0@@Z"
+// vftable:
+// M32-DAG: [[W_VTABLE:@.*]] = private unnamed_addr constant { [2 x i8*] } { [2 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"??_R4W@@6B@" to i8*), i8* bitcast (void (%struct.W*)* @"?foo@W@@UAEXXZ" to i8*)] }, comdat($"??_7W@@6B@")
+// M32-DAG: @"??_7W@@6B@" = dllexport unnamed_addr alias i8*, getelementptr inbounds ({ [2 x i8*] }, { [2 x i8*] }* [[W_VTABLE]], i32 0, i32 0, i32 1)
+// G32-DAG: @_ZTV1W = dso_local dllexport unnamed_addr constant { [3 x i8*] } { [3 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTI1W to i8*), i8* bitcast (void (%struct.W*)* @_ZN1W3fooEv to i8*)] }
+
+struct __declspec(dllexport) X : public virtual W {};
+// vbtable:
+// M32-DAG: @"??_8X@@7B@" = weak_odr dllexport unnamed_addr constant [2 x i32] [i32 0, i32 4]
+
+struct __declspec(dllexport) Y {
+ // Move assignment operator:
+ // MSVC2015-DAG: define weak_odr dso_local dllexport {{.+}} @"??4Y@@Q{{.+}}@$$Q{{.+}}@@Z"
+ // MSVC2013-DAG: define weak_odr dso_local dllexport {{.+}} @"??4Y@@Q{{.+}}0@A{{.+}}0@@Z"
+
+ int x;
+};
+
+struct __declspec(dllexport) Z { virtual ~Z() {} };
+// The scalar deleting dtor does not get exported:
+// M32-DAG: define linkonce_odr dso_local x86_thiscallcc i8* @"??_GZ@@UAEPAXI@Z"
+
+
+// The user-defined dtor does get exported:
+// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"??1Z@@UAE@XZ"
+
+namespace UseDtorAlias {
+ struct __declspec(dllexport) A { ~A(); };
+ struct __declspec(dllexport) B : A { ~B(); };
+ A::~A() { }
+ B::~B() { }
+ // Emit a alias definition of B's constructor.
+ // M32-DAG: @"??1B@UseDtorAlias@@QAE@XZ" = dso_local dllexport unnamed_addr alias {{.*}} @"??1A@UseDtorAlias@@QAE@XZ"
+}
+
+struct __declspec(dllexport) DefaultedCtorsDtors {
+ DefaultedCtorsDtors() = default;
+ // M32MSVC2013-DAG: define weak_odr dso_local dllexport x86_thiscallcc %struct.DefaultedCtorsDtors* @"??0DefaultedCtorsDtors@@QAE@XZ"
+ ~DefaultedCtorsDtors() = default;
+ // M32MSVC2013-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"??1DefaultedCtorsDtors@@QAE@XZ"
+};
+
+// Export defaulted member function definitions declared inside class.
+struct __declspec(dllexport) ExportDefaultedInclassDefs {
+ ExportDefaultedInclassDefs() = default;
+ // M32VS2013-DAG: define weak_odr dso_local dllexport x86_thiscallcc %struct.ExportDefaultedInclassDefs* @"??0ExportDefaultedInclassDefs@@QAE@XZ"(%struct.ExportDefaultedInclassDefs* returned %this)
+ // M64VS2013-DAG: define weak_odr dso_local dllexport %struct.ExportDefaultedInclassDefs* @"??0ExportDefaultedInclassDefs@@QEAA@XZ"(%struct.ExportDefaultedInclassDefs* returned %this)
+ // M32VS2015-NOT: define weak_odr dso_local dllexport x86_thiscallcc %struct.ExportDefaultedInclassDefs* @"??0ExportDefaultedInclassDefs@@QAE@XZ"(%struct.ExportDefaultedInclassDefs* returned %this)
+ // M64VS2015-NOT: define weak_odr dso_local dllexport %struct.ExportDefaultedInclassDefs* @"??0ExportDefaultedInclassDefs@@QEAA@XZ"(%struct.ExportDefaultedInclassDefs* returned %this)
+
+ ~ExportDefaultedInclassDefs() = default;
+ // M32VS2013-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"??1ExportDefaultedInclassDefs@@QAE@XZ"(%struct.ExportDefaultedInclassDefs* %this)
+ // M64VS2013-DAG: define weak_odr dso_local dllexport void @"??1ExportDefaultedInclassDefs@@QEAA@XZ"(%struct.ExportDefaultedInclassDefs* %this)
+ // M32VS2015-NOT: define weak_odr dso_local dllexport x86_thiscallcc void @"??1ExportDefaultedInclassDefs@@QAE@XZ"(%struct.ExportDefaultedInclassDefs* %this)
+ // M64VS2015-NOT: define weak_odr dso_local dllexport void @"??1ExportDefaultedInclassDefs@@QEAA@XZ"(%struct.ExportDefaultedInclassDefs* %this)
+
+ ExportDefaultedInclassDefs(const ExportDefaultedInclassDefs&) = default;
+ // M32VS2013-DAG: define weak_odr dso_local dllexport x86_thiscallcc %struct.ExportDefaultedInclassDefs* @"??0ExportDefaultedInclassDefs@@QAE@ABU0@@Z"(%struct.ExportDefaultedInclassDefs* returned %this, %struct.ExportDefaultedInclassDefs* dereferenceable({{[0-9]+}}))
+ // M64VS2013-DAG: define weak_odr dso_local dllexport %struct.ExportDefaultedInclassDefs* @"??0ExportDefaultedInclassDefs@@QEAA@AEBU0@@Z"(%struct.ExportDefaultedInclassDefs* returned %this, %struct.ExportDefaultedInclassDefs* dereferenceable({{[0-9]+}}))
+ // M32VS2015-NOT: define weak_odr dso_local dllexport x86_thiscallcc %struct.ExportDefaultedInclassDefs* @"??0ExportDefaultedInclassDefs@@QAE@ABU0@@Z"(%struct.ExportDefaultedInclassDefs* returned %this, %struct.ExportDefaultedInclassDefs* dereferenceable({{[0-9]+}}))
+ // M64VS2015-NOT: define weak_odr dso_local dllexport %struct.ExportDefaultedInclassDefs* @"??0ExportDefaultedInclassDefs@@QEAA@AEBU0@@Z"(%struct.ExportDefaultedInclassDefs* returned %this, %struct.ExportDefaultedInclassDefs* dereferenceable({{[0-9]+}}))
+
+ ExportDefaultedInclassDefs& operator=(const ExportDefaultedInclassDefs&) = default;
+ // M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ExportDefaultedInclassDefs* @"??4ExportDefaultedInclassDefs@@QAEAAU0@ABU0@@Z"(%struct.ExportDefaultedInclassDefs* %this, %struct.ExportDefaultedInclassDefs* dereferenceable({{[0-9]+}}))
+ // M64-DAG: define weak_odr dso_local dllexport dereferenceable({{[0-9]+}}) %struct.ExportDefaultedInclassDefs* @"??4ExportDefaultedInclassDefs@@QEAAAEAU0@AEBU0@@Z"(%struct.ExportDefaultedInclassDefs* %this, %struct.ExportDefaultedInclassDefs* dereferenceable({{[0-9]+}}))
+};
+
+namespace ReferencedInlineMethodInNestedClass {
+ struct __declspec(dllexport) S {
+ void foo() {
+ t->bar();
+ }
+ struct T {
+ void bar() {}
+ };
+ T *t;
+ };
+ // M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?foo@S@ReferencedInlineMethodInNestedClass@@QAEXXZ"
+ // M32-DAG: define linkonce_odr dso_local x86_thiscallcc void @"?bar@T@S@ReferencedInlineMethodInNestedClass@@QAEXXZ"
+}
+
+// MS ignores DLL attributes on partial specializations.
+template <typename T> struct PartiallySpecializedClassTemplate {};
+template <typename T> struct __declspec(dllexport) PartiallySpecializedClassTemplate<T*> { void f(); };
+template <typename T> void PartiallySpecializedClassTemplate<T*>::f() {}
+USEMEMFUNC(PartiallySpecializedClassTemplate<void*>, f);
+// M32-DAG: define linkonce_odr dso_local x86_thiscallcc void @"?f@?$PartiallySpecializedClassTemplate@PAX@@QAEXXZ"
+// G32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @_ZN33PartiallySpecializedClassTemplateIPvE1fEv
+
+// Attributes on explicit specializations are honored.
+template <typename T> struct ExplicitlySpecializedClassTemplate {};
+template <> struct __declspec(dllexport) ExplicitlySpecializedClassTemplate<void*> { void f(); };
+void ExplicitlySpecializedClassTemplate<void*>::f() {}
+USEMEMFUNC(ExplicitlySpecializedClassTemplate<void*>, f);
+// M32-DAG: define dso_local dllexport x86_thiscallcc void @"?f@?$ExplicitlySpecializedClassTemplate@PAX@@QAEXXZ"
+// G32-DAG: define dso_local dllexport x86_thiscallcc void @_ZN34ExplicitlySpecializedClassTemplateIPvE1fEv
+
+// MS inherits DLL attributes to partial specializations.
+template <typename T> struct __declspec(dllexport) PartiallySpecializedExportedClassTemplate {};
+template <typename T> struct PartiallySpecializedExportedClassTemplate<T*> { void f() {} };
+USEMEMFUNC(PartiallySpecializedExportedClassTemplate<void*>, f);
+// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?f@?$PartiallySpecializedExportedClassTemplate@PAX@@QAEXXZ"
+// G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN41PartiallySpecializedExportedClassTemplateIPvE1fEv
+
+// MS ignores DLL attributes on partial specializations; inheritance still works though.
+template <typename T> struct __declspec(dllexport) PartiallySpecializedExportedClassTemplate2 {};
+template <typename T> struct __declspec(dllimport) PartiallySpecializedExportedClassTemplate2<T*> { void f(); };
+template <typename T> void PartiallySpecializedExportedClassTemplate2<T*>::f() {}
+USEMEMFUNC(PartiallySpecializedExportedClassTemplate2<void*>, f);
+// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?f@?$PartiallySpecializedExportedClassTemplate2@PAX@@QAEXXZ"
+// G32-DAG: declare dllimport x86_thiscallcc void @_ZN42PartiallySpecializedExportedClassTemplate2IPvE1fEv
+
+// Attributes on the instantiation take precedence over attributes on the template.
+template <typename T> struct __declspec(dllimport) ExplicitlyInstantiatedWithDifferentAttr { void f() {} };
+template struct __declspec(dllexport) ExplicitlyInstantiatedWithDifferentAttr<int>;
+USEMEMFUNC(ExplicitlyInstantiatedWithDifferentAttr<int>, f);
+// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?f@?$ExplicitlyInstantiatedWithDifferentAttr@H@@QAEXXZ"
+
+// Don't create weak dllexport aliases. (PR21373)
+struct NonExportedBaseClass {
+ virtual ~NonExportedBaseClass();
+};
+NonExportedBaseClass::~NonExportedBaseClass() {}
+
+struct __declspec(dllexport) ExportedDerivedClass : NonExportedBaseClass {};
+// M32-DAG: weak_odr dso_local dllexport x86_thiscallcc void @"??1ExportedDerivedClass@@UAE@XZ"
+
+// Do not assert about generating code for constexpr functions twice during explicit instantiation (PR21718).
+template <typename T> struct ExplicitInstConstexprMembers {
+ // Copy assignment operator
+ // M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc dereferenceable(1) %struct.ExplicitInstConstexprMembers* @"??4?$ExplicitInstConstexprMembers@X@@QAEAAU0@ABU0@@Z"
+
+ constexpr ExplicitInstConstexprMembers() {}
+ // M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc %struct.ExplicitInstConstexprMembers* @"??0?$ExplicitInstConstexprMembers@X@@QAE@XZ"
+
+ ExplicitInstConstexprMembers(const ExplicitInstConstexprMembers&) = default;
+ // M32MSVC2013-DAG: define weak_odr dso_local dllexport x86_thiscallcc %struct.ExplicitInstConstexprMembers* @"??0?$ExplicitInstConstexprMembers@X@@QAE@ABU0@@Z"
+
+ constexpr int f() const { return 42; }
+ // M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc i32 @"?f@?$ExplicitInstConstexprMembers@X@@QBEHXZ"
+};
+template struct __declspec(dllexport) ExplicitInstConstexprMembers<void>;
+
+template <typename T> struct ExplicitInstantiationDeclTemplate { void f() {} };
+extern template struct __declspec(dllexport) ExplicitInstantiationDeclTemplate<int>;
+USEMEMFUNC(ExplicitInstantiationDeclTemplate<int>, f);
+// M32-DAG: {{declare|define available_externally}} dso_local x86_thiscallcc void @"?f@?$ExplicitInstantiationDeclTemplate@H@@QAEXXZ"
+
+template <typename T> struct __declspec(dllexport) ExplicitInstantiationDeclExportedTemplate { void f() {} };
+extern template struct ExplicitInstantiationDeclExportedTemplate<int>;
+USEMEMFUNC(ExplicitInstantiationDeclExportedTemplate<int>, f);
+// M32-DAG: {{declare|define available_externally}} dso_local x86_thiscallcc void @"?f@?$ExplicitInstantiationDeclExportedTemplate@H@@QAEXXZ"
+
+template <typename T> struct ExplicitInstantiationDeclExportedDefTemplate { void f() {} ExplicitInstantiationDeclExportedDefTemplate() {} };
+extern template struct ExplicitInstantiationDeclExportedDefTemplate<int>;
+template struct __declspec(dllexport) ExplicitInstantiationDeclExportedDefTemplate<int>;
+USEMEMFUNC(ExplicitInstantiationDeclExportedDefTemplate<int>, f);
+// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?f@?$ExplicitInstantiationDeclExportedDefTemplate@H@@QAEXXZ"
+// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc %struct.ExplicitInstantiationDeclExportedDefTemplate* @"??0?$ExplicitInstantiationDeclExportedDefTemplate@H@@QAE@XZ"
+// G32-DAG: define weak_odr dso_local x86_thiscallcc void @_ZN44ExplicitInstantiationDeclExportedDefTemplateIiE1fEv
+
+template <typename T> struct ImplicitInstantiationExportedExplicitInstantiationDefTemplate { virtual void f() {} };
+ImplicitInstantiationExportedExplicitInstantiationDefTemplate<int> ImplicitInstantiationExportedExplicitInstantiationDefTemplateInstance;
+template struct __declspec(dllexport) ImplicitInstantiationExportedExplicitInstantiationDefTemplate<int>;
+USEMEMFUNC(ImplicitInstantiationExportedExplicitInstantiationDefTemplate<int>, f);
+// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?f@?$ImplicitInstantiationExportedExplicitInstantiationDefTemplate@H@@UAEXXZ"
+// G32-DAG: define weak_odr dso_local x86_thiscallcc void @_ZN61ImplicitInstantiationExportedExplicitInstantiationDefTemplateIiE1fEv
+
+template <typename T> struct __declspec(dllexport) ImplicitInstantiationExplicitInstantiationDefExportedTemplate { virtual void f() {} };
+ImplicitInstantiationExplicitInstantiationDefExportedTemplate<int> ImplicitInstantiationExplicitInstantiationDefExportedTemplateInstance;
+template struct ImplicitInstantiationExplicitInstantiationDefExportedTemplate<int>;
+USEMEMFUNC(ImplicitInstantiationExplicitInstantiationDefExportedTemplate<int>, f);
+// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?f@?$ImplicitInstantiationExplicitInstantiationDefExportedTemplate@H@@UAEXXZ"
+// G32-DAG: define weak_odr dso_local x86_thiscallcc void @_ZN61ImplicitInstantiationExplicitInstantiationDefExportedTemplateIiE1fEv
+
+template <typename T> struct __declspec(dllexport) ImplicitInstantiationExportedExplicitInstantiationDefExportedTemplate { virtual void f() {} };
+ImplicitInstantiationExportedExplicitInstantiationDefExportedTemplate<int> ImplicitInstantiationExportedExplicitInstantiationDefExportedTemplateInstance;
+template struct __declspec(dllexport) ImplicitInstantiationExportedExplicitInstantiationDefExportedTemplate<int>;
+USEMEMFUNC(ImplicitInstantiationExportedExplicitInstantiationDefExportedTemplate<int>, f);
+// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?f@?$ImplicitInstantiationExportedExplicitInstantiationDefExportedTemplate@H@@UAEXXZ"
+// G32-DAG: define weak_odr dso_local x86_thiscallcc void @_ZN69ImplicitInstantiationExportedExplicitInstantiationDefExportedTemplateIiE1fEv
+
+namespace { struct InternalLinkageType {}; }
+struct __declspec(dllexport) PR23308 {
+ void f(InternalLinkageType*);
+};
+void PR23308::f(InternalLinkageType*) {}
+long use(PR23308* p) { p->f(nullptr); }
+// M32-DAG: define internal x86_thiscallcc void @"?f@PR23308@@QAEXPAUInternalLinkageType@?A0x{{[^@]*}}@@@Z"
+
+template <typename T> struct PR23770BaseTemplate { void f() {} };
+template <typename T> struct PR23770DerivedTemplate : PR23770BaseTemplate<int> {};
+extern template struct PR23770DerivedTemplate<int>;
+template struct __declspec(dllexport) PR23770DerivedTemplate<int>;
+// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?f@?$PR23770BaseTemplate@H@@QAEXXZ"
+
+namespace InClassInits {
+
+struct __declspec(dllexport) S {
+ int x = 42;
+};
+// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc %"struct.InClassInits::S"* @"??0S@InClassInits@@QAE@XZ"
+
+// dllexport an already instantiated class template.
+template <typename T> struct Base {
+ int x = 42;
+};
+Base<int> base;
+struct __declspec(dllexport) T : Base<int> { };
+// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc %"struct.InClassInits::Base"* @"??0?$Base@H@InClassInits@@QAE@XZ"
+
+struct A { A(int); };
+struct __declspec(dllexport) U {
+ // Class with both default constructor closure and in-class initializer.
+ U(A = 0) {}
+ int x = 0;
+};
+// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc %"struct.InClassInits::U"* @"??0U@InClassInits@@QAE@UA@1@@Z"
+
+struct Evil {
+ template <typename T> struct Base {
+ int x = 0;
+ };
+ struct S : Base<int> {};
+ // The already instantiated Base<int> becomes dllexported below, but the
+ // in-class initializer for Base<>::x still hasn't been parsed, so emitting
+ // the default ctor must still be delayed.
+ struct __declspec(dllexport) T : Base<int> {};
+};
+// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc %"struct.InClassInits::Evil::Base"* @"??0?$Base@H@Evil@InClassInits@@QAE@XZ"
+
+template <typename T> struct Foo {};
+template <typename T> struct Bar {
+ Bar<T> &operator=(Foo<T>) {}
+};
+struct __declspec(dllexport) Baz {
+ Bar<int> n;
+};
+// After parsing Baz, in ActOnFinishCXXNonNestedClass we would synthesize
+// Baz's operator=, causing instantiation of Foo<int> after which
+// ActOnFinishCXXNonNestedClass is called, and we would bite our own tail.
+// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc dereferenceable(1) %"struct.InClassInits::Baz"* @"??4Baz@InClassInits@@QAEAAU01@ABU01@@Z"
+}
+
+// We had an issue where instantiating A would force emission of B's delayed
+// exported methods.
+namespace pr26490 {
+template <typename T> struct A { };
+struct __declspec(dllexport) B {
+ B(int = 0) {}
+ A<int> m_fn1() {}
+};
+// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"??_FB@pr26490@@QAEXXZ"
+}
+
+// dllexport trumps dllimport on an explicit instantiation.
+template <typename T> struct ExplicitInstantiationTwoAttributes { void f() {} };
+template struct __declspec(dllexport) __declspec(dllimport) ExplicitInstantiationTwoAttributes<int>;
+// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?f@?$ExplicitInstantiationTwoAttributes@H@@QAEXXZ"
+
+namespace pr34849 {
+// Specializations of exported class template member functions get exported.
+template <typename> struct __declspec(dllexport) ExportedClassTemplate { void foo(); };
+template<> void ExportedClassTemplate<int>::foo() {}
+template struct ExportedClassTemplate<int>;
+// M32-DAG: define dso_local dllexport x86_thiscallcc void @"?foo@?$ExportedClassTemplate@H@pr34849@@QAEXXZ"
+
+// Specializations of exported class member template functions do not get exported.
+struct __declspec(dllexport) ExportedClass { template <typename> void bar() ; };
+template<> void ExportedClass::bar<int>() {}
+// M32-DAG: define dso_local x86_thiscallcc void @"??$bar@H@ExportedClass@pr34849@@QAEXXZ"
+template <typename> struct __declspec(dllexport) ExportedClassTemplate2 { template <typename> void baz(); };
+template<> template<> void ExportedClassTemplate2<int>::baz<int>() {}
+// M32-DAG: define dso_local x86_thiscallcc void @"??$baz@H@?$ExportedClassTemplate2@H@pr34849@@QAEXXZ"
+}
+
+//===----------------------------------------------------------------------===//
+// Classes with template base classes
+//===----------------------------------------------------------------------===//
+
+template <typename T> struct ClassTemplate { void func(); };
+template <typename T> void ClassTemplate<T>::func() {}
+template <typename T> struct __declspec(dllexport) ExportedClassTemplate { void func(); };
+template <typename T> void ExportedClassTemplate<T>::func() {}
+template <typename T> struct __declspec(dllimport) ImportedClassTemplate { void func(); };
+template <typename T> void ImportedClassTemplate<T>::func() {}
+
+template <typename T> struct ExplicitlySpecializedTemplate { void func() {} };
+template <> struct ExplicitlySpecializedTemplate<int> { void func(); };
+void ExplicitlySpecializedTemplate<int>::func() {}
+template <typename T> struct ExplicitlyExportSpecializedTemplate { void func() {} };
+template <> struct __declspec(dllexport) ExplicitlyExportSpecializedTemplate<int> { void func(); };
+void ExplicitlyExportSpecializedTemplate<int>::func() {}
+template <typename T> struct ExplicitlyImportSpecializedTemplate { void func(); };
+template <> struct __declspec(dllimport) ExplicitlyImportSpecializedTemplate<int> { void func(); };
+
+template <typename T> struct ExplicitlyInstantiatedTemplate { void func(); };
+template <typename T> void ExplicitlyInstantiatedTemplate<T>::func() {}
+template struct ExplicitlyInstantiatedTemplate<int>;
+template <typename T> struct ExplicitlyExportInstantiatedTemplate { void func(); };
+template <typename T> void ExplicitlyExportInstantiatedTemplate<T>::func() {}
+template struct __declspec(dllexport) ExplicitlyExportInstantiatedTemplate<int>;
+template <typename T> struct ExplicitlyImportInstantiatedTemplate { void func(); };
+template struct __declspec(dllimport) ExplicitlyImportInstantiatedTemplate<int>;
+
+
+// MS: ClassTemplate<int> gets exported.
+struct __declspec(dllexport) DerivedFromTemplate : public ClassTemplate<int> {};
+USEMEMFUNC(DerivedFromTemplate, func)
+// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?func@?$ClassTemplate@H@@QAEXXZ"
+// G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN13ClassTemplateIiE4funcEv
+
+// ExportedTemplate is explicitly exported.
+struct __declspec(dllexport) DerivedFromExportedTemplate : public ExportedClassTemplate<int> {};
+USEMEMFUNC(DerivedFromExportedTemplate, func)
+// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?func@?$ExportedClassTemplate@H@@QAEXXZ"
+// G32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @_ZN21ExportedClassTemplateIiE4funcEv
+
+// ImportedClassTemplate is explicitly imported.
+struct __declspec(dllexport) DerivedFromImportedTemplate : public ImportedClassTemplate<int> {};
+USEMEMFUNC(DerivedFromImportedTemplate, func)
+// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"?func@?$ImportedClassTemplate@H@@QAEXXZ"
+// G32-DAG: declare dllimport x86_thiscallcc void @_ZN21ImportedClassTemplateIiE4funcEv
+
+// Base class already implicitly instantiated without dll attribute.
+struct DerivedFromTemplateD : public ClassTemplate<double> {};
+struct __declspec(dllexport) DerivedFromTemplateD2 : public ClassTemplate<double> {};
+USEMEMFUNC(DerivedFromTemplateD2, func)
+// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?func@?$ClassTemplate@N@@QAEXXZ"
+// G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN13ClassTemplateIdE4funcEv
+
+// MS: Base class already instantiated with different dll attribute.
+struct __declspec(dllimport) DerivedFromTemplateB : public ClassTemplate<bool> {};
+struct __declspec(dllexport) DerivedFromTemplateB2 : public ClassTemplate<bool> {};
+USEMEMFUNC(DerivedFromTemplateB2, func)
+// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"?func@?$ClassTemplate@_N@@QAEXXZ"
+// G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN13ClassTemplateIbE4funcEv
+
+// Base class already specialized without dll attribute.
+struct __declspec(dllexport) DerivedFromExplicitlySpecializedTemplate : public ExplicitlySpecializedTemplate<int> {};
+USEMEMFUNC(DerivedFromExplicitlySpecializedTemplate, func)
+// M32-DAG: define dso_local x86_thiscallcc void @"?func@?$ExplicitlySpecializedTemplate@H@@QAEXXZ"
+// G32-DAG: define dso_local x86_thiscallcc void @_ZN29ExplicitlySpecializedTemplateIiE4funcEv
+
+// Base class alredy specialized with export attribute.
+struct __declspec(dllexport) DerivedFromExplicitlyExportSpecializedTemplate : public ExplicitlyExportSpecializedTemplate<int> {};
+USEMEMFUNC(DerivedFromExplicitlyExportSpecializedTemplate, func)
+// M32-DAG: define dso_local dllexport x86_thiscallcc void @"?func@?$ExplicitlyExportSpecializedTemplate@H@@QAEXXZ"
+// G32-DAG: define dso_local dllexport x86_thiscallcc void @_ZN35ExplicitlyExportSpecializedTemplateIiE4funcEv
+
+// Base class already specialized with import attribute.
+struct __declspec(dllexport) DerivedFromExplicitlyImportSpecializedTemplate : public ExplicitlyImportSpecializedTemplate<int> {};
+USEMEMFUNC(DerivedFromExplicitlyImportSpecializedTemplate, func)
+// M32-DAG: declare dllimport x86_thiscallcc void @"?func@?$ExplicitlyImportSpecializedTemplate@H@@QAEXXZ"
+// G32-DAG: declare dllimport x86_thiscallcc void @_ZN35ExplicitlyImportSpecializedTemplateIiE4funcEv
+
+// Base class already instantiated without dll attribute.
+struct __declspec(dllexport) DerivedFromExplicitlyInstantiatedTemplate : public ExplicitlyInstantiatedTemplate<int> {};
+USEMEMFUNC(DerivedFromExplicitlyInstantiatedTemplate, func)
+// M32-DAG: define weak_odr dso_local x86_thiscallcc void @"?func@?$ExplicitlyInstantiatedTemplate@H@@QAEXXZ"
+// G32-DAG: define weak_odr dso_local x86_thiscallcc void @_ZN30ExplicitlyInstantiatedTemplateIiE4funcEv
+
+// Base class already instantiated with export attribute.
+struct __declspec(dllexport) DerivedFromExplicitlyExportInstantiatedTemplate : public ExplicitlyExportInstantiatedTemplate<int> {};
+USEMEMFUNC(DerivedFromExplicitlyExportInstantiatedTemplate, func)
+// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?func@?$ExplicitlyExportInstantiatedTemplate@H@@QAEXXZ"
+// G32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @_ZN36ExplicitlyExportInstantiatedTemplateIiE4funcEv
+
+// Base class already instantiated with import attribute.
+struct __declspec(dllexport) DerivedFromExplicitlyImportInstantiatedTemplate : public ExplicitlyImportInstantiatedTemplate<int> {};
+USEMEMFUNC(DerivedFromExplicitlyImportInstantiatedTemplate, func)
+// M32-DAG: declare dllimport x86_thiscallcc void @"?func@?$ExplicitlyImportInstantiatedTemplate@H@@QAEXXZ"
+// G32-DAG: declare dllimport x86_thiscallcc void @_ZN36ExplicitlyImportInstantiatedTemplateIiE4funcEv
+
+// MS: A dll attribute propagates through multiple levels of instantiation.
+template <typename T> struct TopClass { void func() {} };
+template <typename T> struct MiddleClass : public TopClass<T> { };
+struct __declspec(dllexport) BottomClass : public MiddleClass<int> { };
+USEMEMFUNC(BottomClass, func)
+// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?func@?$TopClass@H@@QAEXXZ"
+// G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN8TopClassIiE4funcEv
+
+template <typename T> struct ExplicitInstantiationDeclTemplateBase { void func() {} };
+extern template struct ExplicitInstantiationDeclTemplateBase<int>;
+struct __declspec(dllexport) DerivedFromExplicitInstantiationDeclTemplateBase : public ExplicitInstantiationDeclTemplateBase<int> {};
+template struct ExplicitInstantiationDeclTemplateBase<int>;
+// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?func@?$ExplicitInstantiationDeclTemplateBase@H@@QAEXXZ"
+// G32-DAG: define weak_odr dso_local x86_thiscallcc void @_ZN37ExplicitInstantiationDeclTemplateBaseIiE4funcEv
+
+// PR26076
+struct LayerSelectionBound;
+template <typename> struct Selection {};
+typedef Selection<LayerSelectionBound> LayerSelection;
+struct LayerImpl;
+struct __declspec(dllexport) LayerTreeImpl {
+ struct __declspec(dllexport) ElementLayers {
+ LayerImpl *main = nullptr;
+ };
+ LayerSelection foo;
+};
+// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc %"struct.LayerTreeImpl::ElementLayers"* @"??0ElementLayers@LayerTreeImpl@@QAE@XZ"
+// M64-DAG: define weak_odr dso_local dllexport %"struct.LayerTreeImpl::ElementLayers"* @"??0ElementLayers@LayerTreeImpl@@QEAA@XZ"
+
+namespace pr39496 {
+// Make sure dll attribute are inherited by static locals also in template
+// specializations.
+template <typename> struct __declspec(dllexport) S { int foo() { static int x; return x++; } };
+int foo() { S<int> s; return s.foo(); }
+// MSC-DAG: @"?x@?{{1|2}}??foo@?$S@H@pr39496@@Q{{[A-Z]*}}HXZ@4HA" = weak_odr dso_local dllexport global i32 0, comdat, align 4
+
+template <typename> struct T { int foo() { static int x; return x++; } };
+template struct __declspec(dllexport) T<int>;
+// MSC-DAG: @"?x@?{{1|2}}??foo@?$T@H@pr39496@@Q{{[A-Z]*}}HXZ@4HA" = weak_odr dso_local dllexport global i32 0, comdat, align 4
+}
+
+class __declspec(dllexport) ACE_Shared_Object {
+public:
+ virtual ~ACE_Shared_Object();
+};
+class __declspec(dllexport) ACE_Service_Object : public ACE_Shared_Object {};
+// Implicit move constructor declaration.
+// MSVC2015-DAG: define weak_odr dso_local dllexport {{.+}}ACE_Service_Object@@Q{{.+}}@$$Q
+// The declarations should not be exported.
+// MSVC2013-NOT: define weak_odr dso_local dllexport {{.+}}ACE_Service_Object@@Q{{.+}}@$$Q
diff --git a/src/llvm-project/clang/test/CodeGenCXX/dllimport-dtor-thunks.cpp b/src/llvm-project/clang/test/CodeGenCXX/dllimport-dtor-thunks.cpp
new file mode 100644
index 0000000..da3227a
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/dllimport-dtor-thunks.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -mconstructor-aliases %s -triple x86_64-windows-msvc -fms-extensions -emit-llvm -o - | FileCheck %s
+
+// PR32990
+
+// Introduces the virtual destructor. We should use the base destructor
+// directly, no thunk needed.
+struct __declspec(dllimport) ImportIntroVDtor {
+ virtual ~ImportIntroVDtor() {}
+};
+
+struct BaseClass {
+ virtual ~BaseClass() {}
+};
+
+// Non-virtually inherits from a non-dllimport base class. We should again call
+// the derived base constructor directly. No need for the complete (aka vbase)
+// destructor.
+struct __declspec(dllimport) ImportOverrideVDtor : public BaseClass {
+ virtual ~ImportOverrideVDtor() {}
+};
+
+// Virtually inherits from a non-dllimport base class. This time we need to call
+// the complete destructor and emit it inline. It's not exported from the DLL,
+// and it must be emitted.
+struct __declspec(dllimport) ImportVBaseOverrideVDtor
+ : public virtual BaseClass {
+ virtual ~ImportVBaseOverrideVDtor() {}
+};
+
+extern "C" void testit() {
+ ImportIntroVDtor t1;
+ ImportOverrideVDtor t2;
+ ImportVBaseOverrideVDtor t3;
+}
+
+// The destructors are called in reverse order of construction. Only the third
+// needs the complete destructor (_D).
+// CHECK-LABEL: define dso_local void @testit()
+// CHECK: call void @"??_DImportVBaseOverrideVDtor@@QEAAXXZ"(%struct.ImportVBaseOverrideVDtor* %{{.*}})
+// CHECK: call void @"??1ImportOverrideVDtor@@UEAA@XZ"(%struct.ImportOverrideVDtor* %{{.*}})
+// CHECK: call void @"??1ImportIntroVDtor@@UEAA@XZ"(%struct.ImportIntroVDtor* %{{.*}})
+
+// CHECK-LABEL: declare dllimport void @"??_DImportVBaseOverrideVDtor@@QEAAXXZ"
+// CHECK-LABEL: declare dllimport void @"??1ImportOverrideVDtor@@UEAA@XZ"
+// CHECK-LABEL: declare dllimport void @"??1ImportIntroVDtor@@UEAA@XZ"
diff --git a/src/llvm-project/clang/test/CodeGenCXX/dllimport-members.cpp b/src/llvm-project/clang/test/CodeGenCXX/dllimport-members.cpp
new file mode 100644
index 0000000..f8034cf
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/dllimport-members.cpp
@@ -0,0 +1,877 @@
+// RUN: %clang_cc1 -triple i686-windows-msvc -fms-compatibility -emit-llvm -std=c++1y -O0 -o - %s -DMSABI | FileCheck --check-prefix=MSC --check-prefix=M32 %s
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -fms-compatibility -emit-llvm -std=c++1y -O0 -o - %s -DMSABI | FileCheck --check-prefix=MSC --check-prefix=M64 %s
+// RUN: %clang_cc1 -triple i686-windows-gnu -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=GNU --check-prefix=G32 %s
+// RUN: %clang_cc1 -triple x86_64-windows-gnu -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=GNU --check-prefix=G64 %s
+// RUN: %clang_cc1 -triple i686-windows-msvc -fms-compatibility -emit-llvm -std=c++1y -O1 -o - %s -DMSABI | FileCheck --check-prefix=MO1 %s
+// RUN: %clang_cc1 -triple i686-windows-gnu -emit-llvm -std=c++1y -O1 -o - %s | FileCheck --check-prefix=GO1 %s
+
+// Helper structs to make templates more expressive.
+struct ImplicitInst_Imported {};
+struct ExplicitDecl_Imported {};
+struct ExplicitInst_Imported {};
+struct ExplicitSpec_Imported {};
+struct ExplicitSpec_Def_Imported {};
+struct ExplicitSpec_InlineDef_Imported {};
+struct ExplicitSpec_NotImported {};
+
+#define JOIN2(x, y) x##y
+#define JOIN(x, y) JOIN2(x, y)
+#define UNIQ(name) JOIN(name, __LINE__)
+#define USE(func) void UNIQ(use)() { func(); }
+#define USEMV(cls, var) int UNIQ(use)() { return ref(cls::var); }
+#define USEMF(cls, fun) template<> void useMemFun<__LINE__, cls>() { cls().fun(); }
+#define USESPECIALS(cls) void UNIQ(use)() { useSpecials<cls>(); }
+
+template<typename T>
+T ref(T const& v) { return v; }
+
+template<int Line, typename T>
+void useMemFun();
+
+template<typename T>
+void useSpecials() {
+ T v; // Default constructor
+
+ T c1(static_cast<const T&>(v)); // Copy constructor
+ T c2 = static_cast<const T&>(v); // Copy constructor
+ T c3;
+ c3 = static_cast<const T&>(v); // Copy assignment
+
+ T m1(static_cast<T&&>(v)); // Move constructor
+ T m2 = static_cast<T&&>(v); // Move constructor
+ T m3;
+ m3 = static_cast<T&&>(v); // Move assignment
+}
+
+// Used to force non-trivial special members.
+struct __declspec(dllimport) ForceNonTrivial {
+ ForceNonTrivial();
+ ~ForceNonTrivial();
+ ForceNonTrivial(const ForceNonTrivial&);
+ ForceNonTrivial& operator=(const ForceNonTrivial&);
+ ForceNonTrivial(ForceNonTrivial&&);
+ ForceNonTrivial& operator=(ForceNonTrivial&&);
+};
+
+
+
+//===----------------------------------------------------------------------===//
+// Class members
+//===----------------------------------------------------------------------===//
+
+// Import individual members of a class.
+struct ImportMembers {
+ struct Nested;
+
+ // M32-DAG: define dso_local dllexport x86_thiscallcc void @"?normalDef@ImportMembers@@QAEXXZ"(%struct.ImportMembers* %this)
+ // M64-DAG: define dso_local dllexport void @"?normalDef@ImportMembers@@QEAAXXZ"(%struct.ImportMembers* %this)
+ // M32-DAG: declare dllimport x86_thiscallcc void @"?normalDecl@ImportMembers@@QAEXXZ"(%struct.ImportMembers*)
+ // M64-DAG: declare dllimport void @"?normalDecl@ImportMembers@@QEAAXXZ"(%struct.ImportMembers*)
+ // M32-DAG: declare dllimport x86_thiscallcc void @"?normalInclass@ImportMembers@@QAEXXZ"(%struct.ImportMembers*)
+ // M64-DAG: declare dllimport void @"?normalInclass@ImportMembers@@QEAAXXZ"(%struct.ImportMembers*)
+ // M32-DAG: declare dllimport x86_thiscallcc void @"?normalInlineDef@ImportMembers@@QAEXXZ"(%struct.ImportMembers*)
+ // M64-DAG: declare dllimport void @"?normalInlineDef@ImportMembers@@QEAAXXZ"(%struct.ImportMembers*)
+ // M32-DAG: declare dllimport x86_thiscallcc void @"?normalInlineDecl@ImportMembers@@QAEXXZ"(%struct.ImportMembers*)
+ // M64-DAG: declare dllimport void @"?normalInlineDecl@ImportMembers@@QEAAXXZ"(%struct.ImportMembers*)
+ // G32-DAG: define dso_local x86_thiscallcc void @_ZN13ImportMembers9normalDefEv(%struct.ImportMembers* %this)
+ // G64-DAG: define dso_local void @_ZN13ImportMembers9normalDefEv(%struct.ImportMembers* %this)
+ // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers10normalDeclEv(%struct.ImportMembers*)
+ // G64-DAG: declare dllimport void @_ZN13ImportMembers10normalDeclEv(%struct.ImportMembers*)
+ // G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN13ImportMembers13normalInclassEv(%struct.ImportMembers* %this)
+ // G64-DAG: define linkonce_odr dso_local void @_ZN13ImportMembers13normalInclassEv(%struct.ImportMembers* %this)
+ // G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN13ImportMembers15normalInlineDefEv(%struct.ImportMembers* %this)
+ // G64-DAG: define linkonce_odr dso_local void @_ZN13ImportMembers15normalInlineDefEv(%struct.ImportMembers* %this)
+ // G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN13ImportMembers16normalInlineDeclEv(%struct.ImportMembers* %this)
+ // G64-DAG: define linkonce_odr dso_local void @_ZN13ImportMembers16normalInlineDeclEv(%struct.ImportMembers* %this)
+ // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"?normalInclass@ImportMembers@@QAEXXZ"(
+ // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"?normalInlineDef@ImportMembers@@QAEXXZ"(
+ // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"?normalInlineDecl@ImportMembers@@QAEXXZ"(
+ // GO1-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN13ImportMembers13normalInclassEv(
+ // GO1-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN13ImportMembers15normalInlineDefEv(
+ // GO1-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN13ImportMembers16normalInlineDeclEv(
+ __declspec(dllimport) void normalDef(); // dllimport ignored
+ __declspec(dllimport) void normalDecl();
+ __declspec(dllimport) void normalInclass() {}
+ __declspec(dllimport) void normalInlineDef();
+ __declspec(dllimport) inline void normalInlineDecl();
+
+ // M32-DAG: define dso_local dllexport x86_thiscallcc void @"?virtualDef@ImportMembers@@UAEXXZ"(%struct.ImportMembers* %this)
+ // M64-DAG: define dso_local dllexport void @"?virtualDef@ImportMembers@@UEAAXXZ"(%struct.ImportMembers* %this)
+ // M32-DAG: declare dllimport x86_thiscallcc void @"?virtualDecl@ImportMembers@@UAEXXZ"(%struct.ImportMembers*)
+ // M64-DAG: declare dllimport void @"?virtualDecl@ImportMembers@@UEAAXXZ"(%struct.ImportMembers*)
+ // M32-DAG: declare dllimport x86_thiscallcc void @"?virtualInclass@ImportMembers@@UAEXXZ"(%struct.ImportMembers*)
+ // M64-DAG: declare dllimport void @"?virtualInclass@ImportMembers@@UEAAXXZ"(%struct.ImportMembers*)
+ // M32-DAG: declare dllimport x86_thiscallcc void @"?virtualInlineDef@ImportMembers@@UAEXXZ"(%struct.ImportMembers*)
+ // M64-DAG: declare dllimport void @"?virtualInlineDef@ImportMembers@@UEAAXXZ"(%struct.ImportMembers*)
+ // M32-DAG: declare dllimport x86_thiscallcc void @"?virtualInlineDecl@ImportMembers@@UAEXXZ"(%struct.ImportMembers*)
+ // M64-DAG: declare dllimport void @"?virtualInlineDecl@ImportMembers@@UEAAXXZ"(%struct.ImportMembers*)
+ // G32-DAG: define dso_local x86_thiscallcc void @_ZN13ImportMembers10virtualDefEv(%struct.ImportMembers* %this)
+ // G64-DAG: define dso_local void @_ZN13ImportMembers10virtualDefEv(%struct.ImportMembers* %this)
+ // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers11virtualDeclEv(%struct.ImportMembers*)
+ // G64-DAG: declare dllimport void @_ZN13ImportMembers11virtualDeclEv(%struct.ImportMembers*)
+ // G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN13ImportMembers14virtualInclassEv(%struct.ImportMembers* %this)
+ // G64-DAG: define linkonce_odr dso_local void @_ZN13ImportMembers14virtualInclassEv(%struct.ImportMembers* %this)
+ // G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN13ImportMembers16virtualInlineDefEv(%struct.ImportMembers* %this)
+ // G64-DAG: define linkonce_odr dso_local void @_ZN13ImportMembers16virtualInlineDefEv(%struct.ImportMembers* %this)
+ // G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN13ImportMembers17virtualInlineDeclEv(%struct.ImportMembers* %this)
+ // G64-DAG: define linkonce_odr dso_local void @_ZN13ImportMembers17virtualInlineDeclEv(%struct.ImportMembers* %this)
+ // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"?virtualInclass@ImportMembers@@UAEXXZ"(
+ // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"?virtualInlineDef@ImportMembers@@UAEXXZ"(
+ // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"?virtualInlineDecl@ImportMembers@@UAEXXZ"(
+ // GO1-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN13ImportMembers14virtualInclassEv(
+ // GO1-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN13ImportMembers16virtualInlineDefEv(
+ // GO1-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN13ImportMembers17virtualInlineDeclEv(
+ __declspec(dllimport) virtual void virtualDef(); // dllimport ignored
+ __declspec(dllimport) virtual void virtualDecl();
+ __declspec(dllimport) virtual void virtualInclass() {}
+ __declspec(dllimport) virtual void virtualInlineDef();
+ __declspec(dllimport) virtual inline void virtualInlineDecl();
+
+ // MSC-DAG: define dso_local dllexport void @"?staticDef@ImportMembers@@SAXXZ"()
+ // MSC-DAG: declare dllimport void @"?staticDecl@ImportMembers@@SAXXZ"()
+ // MSC-DAG: declare dllimport void @"?staticInclass@ImportMembers@@SAXXZ"()
+ // MSC-DAG: declare dllimport void @"?staticInlineDef@ImportMembers@@SAXXZ"()
+ // MSC-DAG: declare dllimport void @"?staticInlineDecl@ImportMembers@@SAXXZ"()
+ // GNU-DAG: define dso_local void @_ZN13ImportMembers9staticDefEv()
+ // GNU-DAG: declare dllimport void @_ZN13ImportMembers10staticDeclEv()
+ // GNU-DAG: define linkonce_odr dso_local void @_ZN13ImportMembers13staticInclassEv()
+ // GNU-DAG: define linkonce_odr dso_local void @_ZN13ImportMembers15staticInlineDefEv()
+ // GNU-DAG: define linkonce_odr dso_local void @_ZN13ImportMembers16staticInlineDeclEv()
+ // MO1-DAG: define available_externally dllimport void @"?staticInclass@ImportMembers@@SAXXZ"()
+ // MO1-DAG: define available_externally dllimport void @"?staticInlineDef@ImportMembers@@SAXXZ"()
+ // MO1-DAG: define available_externally dllimport void @"?staticInlineDecl@ImportMembers@@SAXXZ"()
+ // GO1-DAG: define linkonce_odr dso_local void @_ZN13ImportMembers13staticInclassEv()
+ // GO1-DAG: define linkonce_odr dso_local void @_ZN13ImportMembers15staticInlineDefEv()
+ // GO1-DAG: define linkonce_odr dso_local void @_ZN13ImportMembers16staticInlineDeclEv()
+ __declspec(dllimport) static void staticDef(); // dllimport ignored
+ __declspec(dllimport) static void staticDecl();
+ __declspec(dllimport) static void staticInclass() {}
+ __declspec(dllimport) static void staticInlineDef();
+ __declspec(dllimport) static inline void staticInlineDecl();
+
+ // M32-DAG: declare dllimport x86_thiscallcc void @"?protectedNormalDecl@ImportMembers@@IAEXXZ"(%struct.ImportMembers*)
+ // M64-DAG: declare dllimport void @"?protectedNormalDecl@ImportMembers@@IEAAXXZ"(%struct.ImportMembers*)
+ // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers19protectedNormalDeclEv(%struct.ImportMembers*)
+ // G64-DAG: declare dllimport void @_ZN13ImportMembers19protectedNormalDeclEv(%struct.ImportMembers*)
+ // MSC-DAG: declare dllimport void @"?protectedStaticDecl@ImportMembers@@KAXXZ"()
+ // GNU-DAG: declare dllimport void @_ZN13ImportMembers19protectedStaticDeclEv()
+protected:
+ __declspec(dllimport) void protectedNormalDecl();
+ __declspec(dllimport) static void protectedStaticDecl();
+
+ // M32-DAG: declare dllimport x86_thiscallcc void @"?privateNormalDecl@ImportMembers@@AAEXXZ"(%struct.ImportMembers*)
+ // M64-DAG: declare dllimport void @"?privateNormalDecl@ImportMembers@@AEAAXXZ"(%struct.ImportMembers*)
+ // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers17privateNormalDeclEv(%struct.ImportMembers*)
+ // G64-DAG: declare dllimport void @_ZN13ImportMembers17privateNormalDeclEv(%struct.ImportMembers*)
+ // MSC-DAG: declare dllimport void @"?privateStaticDecl@ImportMembers@@CAXXZ"()
+ // GNU-DAG: declare dllimport void @_ZN13ImportMembers17privateStaticDeclEv()
+private:
+ __declspec(dllimport) void privateNormalDecl();
+ __declspec(dllimport) static void privateStaticDecl();
+
+ // M32-DAG: declare dso_local x86_thiscallcc void @"?ignored@ImportMembers@@QAEXXZ"(%struct.ImportMembers*)
+ // M64-DAG: declare dso_local void @"?ignored@ImportMembers@@QEAAXXZ"(%struct.ImportMembers*)
+ // G32-DAG: declare dso_local x86_thiscallcc void @_ZN13ImportMembers7ignoredEv(%struct.ImportMembers*)
+ // G64-DAG: declare dso_local void @_ZN13ImportMembers7ignoredEv(%struct.ImportMembers*)
+public:
+ void ignored();
+
+ // MSC-DAG: @"?StaticField@ImportMembers@@2HA" = external dllimport global i32
+ // MSC-DAG: @"?StaticConstField@ImportMembers@@2HB" = external dllimport constant i32
+ // MSC-DAG: @"?StaticConstFieldEqualInit@ImportMembers@@2HB" = available_externally dllimport constant i32 1, align 4
+ // MSC-DAG: @"?StaticConstFieldBraceInit@ImportMembers@@2HB" = available_externally dllimport constant i32 1, align 4
+ // MSC-DAG: @"?ConstexprField@ImportMembers@@2HB" = available_externally dllimport constant i32 1, align 4
+ // GNU-DAG: @_ZN13ImportMembers11StaticFieldE = external dllimport global i32
+ // GNU-DAG: @_ZN13ImportMembers16StaticConstFieldE = external dllimport constant i32
+ // GNU-DAG: @_ZN13ImportMembers25StaticConstFieldEqualInitE = external dllimport constant i32
+ // GNU-DAG: @_ZN13ImportMembers25StaticConstFieldBraceInitE = external dllimport constant i32
+ // GNU-DAG: @_ZN13ImportMembers14ConstexprFieldE = external dllimport constant i32
+ __declspec(dllimport) static int StaticField;
+ __declspec(dllimport) static const int StaticConstField;
+ __declspec(dllimport) static const int StaticConstFieldEqualInit = 1;
+ __declspec(dllimport) static const int StaticConstFieldBraceInit{1};
+ __declspec(dllimport) constexpr static int ConstexprField = 1;
+
+ template<int Line, typename T> friend void useMemFun();
+};
+
+ void ImportMembers::normalDef() {} // dllimport ignored
+inline void ImportMembers::normalInlineDef() {}
+ void ImportMembers::normalInlineDecl() {}
+ void ImportMembers::virtualDef() {} // dllimport ignored
+inline void ImportMembers::virtualInlineDef() {}
+ void ImportMembers::virtualInlineDecl() {}
+ void ImportMembers::staticDef() {} // dllimport ignored
+inline void ImportMembers::staticInlineDef() {}
+ void ImportMembers::staticInlineDecl() {}
+
+USEMF(ImportMembers, normalDef)
+USEMF(ImportMembers, normalDecl)
+USEMF(ImportMembers, normalInclass)
+USEMF(ImportMembers, normalInlineDef)
+USEMF(ImportMembers, normalInlineDecl)
+USEMF(ImportMembers, virtualDef)
+USEMF(ImportMembers, virtualDecl)
+USEMF(ImportMembers, virtualInclass)
+USEMF(ImportMembers, virtualInlineDef)
+USEMF(ImportMembers, virtualInlineDecl)
+USEMF(ImportMembers, staticDef)
+USEMF(ImportMembers, staticDecl)
+USEMF(ImportMembers, staticInclass)
+USEMF(ImportMembers, staticInlineDef)
+USEMF(ImportMembers, staticInlineDecl)
+USEMF(ImportMembers, protectedNormalDecl)
+USEMF(ImportMembers, protectedStaticDecl)
+USEMF(ImportMembers, privateNormalDecl)
+USEMF(ImportMembers, privateStaticDecl)
+USEMF(ImportMembers, ignored)
+
+USEMV(ImportMembers, StaticField)
+USEMV(ImportMembers, StaticConstField)
+USEMV(ImportMembers, StaticConstFieldEqualInit)
+USEMV(ImportMembers, StaticConstFieldBraceInit)
+USEMV(ImportMembers, ConstexprField)
+
+
+// Import individual members of a nested class.
+struct ImportMembers::Nested {
+ // M32-DAG: define dso_local dllexport x86_thiscallcc void @"?normalDef@Nested@ImportMembers@@QAEXXZ"(%"struct.ImportMembers::Nested"* %this)
+ // M64-DAG: define dso_local dllexport void @"?normalDef@Nested@ImportMembers@@QEAAXXZ"(%"struct.ImportMembers::Nested"* %this)
+ // M32-DAG: declare dllimport x86_thiscallcc void @"?normalDecl@Nested@ImportMembers@@QAEXXZ"(%"struct.ImportMembers::Nested"*)
+ // M64-DAG: declare dllimport void @"?normalDecl@Nested@ImportMembers@@QEAAXXZ"(%"struct.ImportMembers::Nested"*)
+ // M32-DAG: declare dllimport x86_thiscallcc void @"?normalInclass@Nested@ImportMembers@@QAEXXZ"(%"struct.ImportMembers::Nested"*)
+ // M64-DAG: declare dllimport void @"?normalInclass@Nested@ImportMembers@@QEAAXXZ"(%"struct.ImportMembers::Nested"*)
+ // M32-DAG: declare dllimport x86_thiscallcc void @"?normalInlineDef@Nested@ImportMembers@@QAEXXZ"(%"struct.ImportMembers::Nested"*)
+ // M64-DAG: declare dllimport void @"?normalInlineDef@Nested@ImportMembers@@QEAAXXZ"(%"struct.ImportMembers::Nested"*)
+ // M32-DAG: declare dllimport x86_thiscallcc void @"?normalInlineDecl@Nested@ImportMembers@@QAEXXZ"(%"struct.ImportMembers::Nested"*)
+ // M64-DAG: declare dllimport void @"?normalInlineDecl@Nested@ImportMembers@@QEAAXXZ"(%"struct.ImportMembers::Nested"*)
+ // G32-DAG: define dso_local x86_thiscallcc void @_ZN13ImportMembers6Nested9normalDefEv(%"struct.ImportMembers::Nested"* %this)
+ // G64-DAG: define dso_local void @_ZN13ImportMembers6Nested9normalDefEv(%"struct.ImportMembers::Nested"* %this)
+ // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested10normalDeclEv(%"struct.ImportMembers::Nested"*)
+ // G64-DAG: declare dllimport void @_ZN13ImportMembers6Nested10normalDeclEv(%"struct.ImportMembers::Nested"*)
+ // G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN13ImportMembers6Nested13normalInclassEv(%"struct.ImportMembers::Nested"* %this)
+ // G64-DAG: define linkonce_odr dso_local void @_ZN13ImportMembers6Nested13normalInclassEv(%"struct.ImportMembers::Nested"* %this)
+ // G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN13ImportMembers6Nested15normalInlineDefEv(%"struct.ImportMembers::Nested"* %this)
+ // G64-DAG: define linkonce_odr dso_local void @_ZN13ImportMembers6Nested15normalInlineDefEv(%"struct.ImportMembers::Nested"* %this)
+ // G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN13ImportMembers6Nested16normalInlineDeclEv(%"struct.ImportMembers::Nested"* %this)
+ // G64-DAG: define linkonce_odr dso_local void @_ZN13ImportMembers6Nested16normalInlineDeclEv(%"struct.ImportMembers::Nested"* %this)
+ // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"?normalInclass@Nested@ImportMembers@@QAEXXZ"(
+ // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"?normalInlineDef@Nested@ImportMembers@@QAEXXZ"(
+ // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"?normalInlineDecl@Nested@ImportMembers@@QAEXXZ"(
+ // GO1-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN13ImportMembers6Nested13normalInclassEv(
+ // GO1-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN13ImportMembers6Nested15normalInlineDefEv(
+ // GO1-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN13ImportMembers6Nested16normalInlineDeclEv(
+ __declspec(dllimport) void normalDef(); // dllimport ignored
+ __declspec(dllimport) void normalDecl();
+ __declspec(dllimport) void normalInclass() {}
+ __declspec(dllimport) void normalInlineDef();
+ __declspec(dllimport) inline void normalInlineDecl();
+
+ // M32-DAG: define dso_local dllexport x86_thiscallcc void @"?virtualDef@Nested@ImportMembers@@UAEXXZ"(%"struct.ImportMembers::Nested"* %this)
+ // M64-DAG: define dso_local dllexport void @"?virtualDef@Nested@ImportMembers@@UEAAXXZ"(%"struct.ImportMembers::Nested"* %this)
+ // M32-DAG: declare dllimport x86_thiscallcc void @"?virtualDecl@Nested@ImportMembers@@UAEXXZ"(%"struct.ImportMembers::Nested"*)
+ // M64-DAG: declare dllimport void @"?virtualDecl@Nested@ImportMembers@@UEAAXXZ"(%"struct.ImportMembers::Nested"*)
+ // M32-DAG: declare dllimport x86_thiscallcc void @"?virtualInclass@Nested@ImportMembers@@UAEXXZ"(%"struct.ImportMembers::Nested"*)
+ // M64-DAG: declare dllimport void @"?virtualInclass@Nested@ImportMembers@@UEAAXXZ"(%"struct.ImportMembers::Nested"*)
+ // M32-DAG: declare dllimport x86_thiscallcc void @"?virtualInlineDef@Nested@ImportMembers@@UAEXXZ"(%"struct.ImportMembers::Nested"*)
+ // M64-DAG: declare dllimport void @"?virtualInlineDef@Nested@ImportMembers@@UEAAXXZ"(%"struct.ImportMembers::Nested"*)
+ // M32-DAG: declare dllimport x86_thiscallcc void @"?virtualInlineDecl@Nested@ImportMembers@@UAEXXZ"(%"struct.ImportMembers::Nested"*)
+ // M64-DAG: declare dllimport void @"?virtualInlineDecl@Nested@ImportMembers@@UEAAXXZ"(%"struct.ImportMembers::Nested"*)
+ // G32-DAG: define dso_local x86_thiscallcc void @_ZN13ImportMembers6Nested10virtualDefEv(%"struct.ImportMembers::Nested"* %this)
+ // G64-DAG: define dso_local void @_ZN13ImportMembers6Nested10virtualDefEv(%"struct.ImportMembers::Nested"* %this)
+ // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested11virtualDeclEv(%"struct.ImportMembers::Nested"*)
+ // G64-DAG: declare dllimport void @_ZN13ImportMembers6Nested11virtualDeclEv(%"struct.ImportMembers::Nested"*)
+ // G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN13ImportMembers6Nested14virtualInclassEv(%"struct.ImportMembers::Nested"* %this)
+ // G64-DAG: define linkonce_odr dso_local void @_ZN13ImportMembers6Nested14virtualInclassEv(%"struct.ImportMembers::Nested"* %this)
+ // G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN13ImportMembers6Nested16virtualInlineDefEv(%"struct.ImportMembers::Nested"* %this)
+ // G64-DAG: define linkonce_odr dso_local void @_ZN13ImportMembers6Nested16virtualInlineDefEv(%"struct.ImportMembers::Nested"* %this)
+ // G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN13ImportMembers6Nested17virtualInlineDeclEv(%"struct.ImportMembers::Nested"* %this)
+ // G64-DAG: define linkonce_odr dso_local void @_ZN13ImportMembers6Nested17virtualInlineDeclEv(%"struct.ImportMembers::Nested"* %this)
+
+ // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"?virtualInclass@Nested@ImportMembers@@UAEXXZ"(
+ // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"?virtualInlineDef@Nested@ImportMembers@@UAEXXZ"(
+ // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"?virtualInlineDecl@Nested@ImportMembers@@UAEXXZ"(
+ // GO1-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN13ImportMembers6Nested14virtualInclassEv(
+ // GO1-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN13ImportMembers6Nested16virtualInlineDefEv(
+ // GO1-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN13ImportMembers6Nested17virtualInlineDeclEv(
+ __declspec(dllimport) virtual void virtualDef(); // dllimport ignored
+ __declspec(dllimport) virtual void virtualDecl();
+ __declspec(dllimport) virtual void virtualInclass() {}
+ __declspec(dllimport) virtual void virtualInlineDef();
+ __declspec(dllimport) virtual inline void virtualInlineDecl();
+
+ // MSC-DAG: define dso_local dllexport void @"?staticDef@Nested@ImportMembers@@SAXXZ"()
+ // MSC-DAG: declare dllimport void @"?staticDecl@Nested@ImportMembers@@SAXXZ"()
+ // MSC-DAG: declare dllimport void @"?staticInclass@Nested@ImportMembers@@SAXXZ"()
+ // MSC-DAG: declare dllimport void @"?staticInlineDef@Nested@ImportMembers@@SAXXZ"()
+ // MSC-DAG: declare dllimport void @"?staticInlineDecl@Nested@ImportMembers@@SAXXZ"()
+ // GNU-DAG: define dso_local void @_ZN13ImportMembers6Nested9staticDefEv()
+ // GNU-DAG: declare dllimport void @_ZN13ImportMembers6Nested10staticDeclEv()
+ // GNU-DAG: define linkonce_odr dso_local void @_ZN13ImportMembers6Nested13staticInclassEv()
+ // GNU-DAG: define linkonce_odr dso_local void @_ZN13ImportMembers6Nested15staticInlineDefEv()
+ // GNU-DAG: define linkonce_odr dso_local void @_ZN13ImportMembers6Nested16staticInlineDeclEv()
+ // MO1-DAG: define available_externally dllimport void @"?staticInclass@Nested@ImportMembers@@SAXXZ"()
+ // MO1-DAG: define available_externally dllimport void @"?staticInlineDef@Nested@ImportMembers@@SAXXZ"()
+ // MO1-DAG: define available_externally dllimport void @"?staticInlineDecl@Nested@ImportMembers@@SAXXZ"()
+ // GO1-DAG: define linkonce_odr dso_local void @_ZN13ImportMembers6Nested13staticInclassEv()
+ // GO1-DAG: define linkonce_odr dso_local void @_ZN13ImportMembers6Nested15staticInlineDefEv()
+ // GO1-DAG: define linkonce_odr dso_local void @_ZN13ImportMembers6Nested16staticInlineDeclEv()
+ __declspec(dllimport) static void staticDef(); // dllimport ignored
+ __declspec(dllimport) static void staticDecl();
+ __declspec(dllimport) static void staticInclass() {}
+ __declspec(dllimport) static void staticInlineDef();
+ __declspec(dllimport) static inline void staticInlineDecl();
+
+ // M32-DAG: declare dllimport x86_thiscallcc void @"?protectedNormalDecl@Nested@ImportMembers@@IAEXXZ"(%"struct.ImportMembers::Nested"*)
+ // M64-DAG: declare dllimport void @"?protectedNormalDecl@Nested@ImportMembers@@IEAAXXZ"(%"struct.ImportMembers::Nested"*)
+ // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested19protectedNormalDeclEv(%"struct.ImportMembers::Nested"*)
+ // G64-DAG: declare dllimport void @_ZN13ImportMembers6Nested19protectedNormalDeclEv(%"struct.ImportMembers::Nested"*)
+ // MSC-DAG: declare dllimport void @"?protectedStaticDecl@Nested@ImportMembers@@KAXXZ"()
+ // GNU-DAG: declare dllimport void @_ZN13ImportMembers6Nested19protectedStaticDeclEv()
+protected:
+ __declspec(dllimport) void protectedNormalDecl();
+ __declspec(dllimport) static void protectedStaticDecl();
+
+ // M32-DAG: declare dllimport x86_thiscallcc void @"?privateNormalDecl@Nested@ImportMembers@@AAEXXZ"(%"struct.ImportMembers::Nested"*)
+ // M64-DAG: declare dllimport void @"?privateNormalDecl@Nested@ImportMembers@@AEAAXXZ"(%"struct.ImportMembers::Nested"*)
+ // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested17privateNormalDeclEv(%"struct.ImportMembers::Nested"*)
+ // G64-DAG: declare dllimport void @_ZN13ImportMembers6Nested17privateNormalDeclEv(%"struct.ImportMembers::Nested"*)
+ // MSC-DAG: declare dllimport void @"?privateStaticDecl@Nested@ImportMembers@@CAXXZ"()
+ // GNU-DAG: declare dllimport void @_ZN13ImportMembers6Nested17privateStaticDeclEv()
+private:
+ __declspec(dllimport) void privateNormalDecl();
+ __declspec(dllimport) static void privateStaticDecl();
+
+ // M32-DAG: declare dso_local x86_thiscallcc void @"?ignored@Nested@ImportMembers@@QAEXXZ"(%"struct.ImportMembers::Nested"*)
+ // M64-DAG: declare dso_local void @"?ignored@Nested@ImportMembers@@QEAAXXZ"(%"struct.ImportMembers::Nested"*)
+ // G32-DAG: declare dso_local x86_thiscallcc void @_ZN13ImportMembers6Nested7ignoredEv(%"struct.ImportMembers::Nested"*)
+ // G64-DAG: declare dso_local void @_ZN13ImportMembers6Nested7ignoredEv(%"struct.ImportMembers::Nested"*)
+public:
+ void ignored();
+
+ // MSC-DAG: @"?StaticField@Nested@ImportMembers@@2HA" = external dllimport global i32
+ // MSC-DAG: @"?StaticConstField@Nested@ImportMembers@@2HB" = external dllimport constant i32
+ // MSC-DAG: @"?StaticConstFieldEqualInit@Nested@ImportMembers@@2HB" = available_externally dllimport constant i32 1, align 4
+ // MSC-DAG: @"?StaticConstFieldBraceInit@Nested@ImportMembers@@2HB" = available_externally dllimport constant i32 1, align 4
+ // MSC-DAG: @"?ConstexprField@Nested@ImportMembers@@2HB" = available_externally dllimport constant i32 1, align 4
+ // GNU-DAG: @_ZN13ImportMembers6Nested11StaticFieldE = external dllimport global i32
+ // GNU-DAG: @_ZN13ImportMembers6Nested16StaticConstFieldE = external dllimport constant i32
+ // GNU-DAG: @_ZN13ImportMembers6Nested25StaticConstFieldEqualInitE = external dllimport constant i32
+ // GNU-DAG: @_ZN13ImportMembers6Nested25StaticConstFieldBraceInitE = external dllimport constant i32
+ // GNU-DAG: @_ZN13ImportMembers6Nested14ConstexprFieldE = external dllimport constant i32
+ __declspec(dllimport) static int StaticField;
+ __declspec(dllimport) static const int StaticConstField;
+ __declspec(dllimport) static const int StaticConstFieldEqualInit = 1;
+ __declspec(dllimport) static const int StaticConstFieldBraceInit{1};
+ __declspec(dllimport) constexpr static int ConstexprField = 1;
+
+ template<int Line, typename T> friend void useMemFun();
+};
+
+ void ImportMembers::Nested::normalDef() {} // dllimport ignored
+inline void ImportMembers::Nested::normalInlineDef() {}
+ void ImportMembers::Nested::normalInlineDecl() {}
+ void ImportMembers::Nested::virtualDef() {} // dllimport ignored
+inline void ImportMembers::Nested::virtualInlineDef() {}
+ void ImportMembers::Nested::virtualInlineDecl() {}
+ void ImportMembers::Nested::staticDef() {} // dllimport ignored
+inline void ImportMembers::Nested::staticInlineDef() {}
+ void ImportMembers::Nested::staticInlineDecl() {}
+
+USEMF(ImportMembers::Nested, normalDef)
+USEMF(ImportMembers::Nested, normalDecl)
+USEMF(ImportMembers::Nested, normalInclass)
+USEMF(ImportMembers::Nested, normalInlineDef)
+USEMF(ImportMembers::Nested, normalInlineDecl)
+USEMF(ImportMembers::Nested, virtualDef)
+USEMF(ImportMembers::Nested, virtualDecl)
+USEMF(ImportMembers::Nested, virtualInclass)
+USEMF(ImportMembers::Nested, virtualInlineDef)
+USEMF(ImportMembers::Nested, virtualInlineDecl)
+USEMF(ImportMembers::Nested, staticDef)
+USEMF(ImportMembers::Nested, staticDecl)
+USEMF(ImportMembers::Nested, staticInclass)
+USEMF(ImportMembers::Nested, staticInlineDef)
+USEMF(ImportMembers::Nested, staticInlineDecl)
+USEMF(ImportMembers::Nested, protectedNormalDecl)
+USEMF(ImportMembers::Nested, protectedStaticDecl)
+USEMF(ImportMembers::Nested, privateNormalDecl)
+USEMF(ImportMembers::Nested, privateStaticDecl)
+USEMF(ImportMembers::Nested, ignored)
+
+USEMV(ImportMembers::Nested, StaticField)
+USEMV(ImportMembers::Nested, StaticConstField)
+USEMV(ImportMembers::Nested, StaticConstFieldEqualInit)
+USEMV(ImportMembers::Nested, StaticConstFieldBraceInit)
+USEMV(ImportMembers::Nested, ConstexprField)
+
+
+// Import special member functions.
+struct ImportSpecials {
+ // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportSpecials* @"??0ImportSpecials@@QAE@XZ"(%struct.ImportSpecials* returned)
+ // M64-DAG: declare dllimport %struct.ImportSpecials* @"??0ImportSpecials@@QEAA@XZ"(%struct.ImportSpecials* returned)
+ // G32-DAG: declare dllimport x86_thiscallcc void @_ZN14ImportSpecialsC1Ev(%struct.ImportSpecials*)
+ // G64-DAG: declare dllimport void @_ZN14ImportSpecialsC1Ev(%struct.ImportSpecials*)
+ __declspec(dllimport) ImportSpecials();
+
+ // M32-DAG: declare dllimport x86_thiscallcc void @"??1ImportSpecials@@QAE@XZ"(%struct.ImportSpecials*)
+ // M64-DAG: declare dllimport void @"??1ImportSpecials@@QEAA@XZ"(%struct.ImportSpecials*)
+ // G32-DAG: declare dllimport x86_thiscallcc void @_ZN14ImportSpecialsD1Ev(%struct.ImportSpecials*)
+ // G64-DAG: declare dllimport void @_ZN14ImportSpecialsD1Ev(%struct.ImportSpecials*)
+ __declspec(dllimport) ~ImportSpecials();
+
+ // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportSpecials* @"??0ImportSpecials@@QAE@ABU0@@Z"(%struct.ImportSpecials* returned, %struct.ImportSpecials* dereferenceable({{[0-9]+}}))
+ // M64-DAG: declare dllimport %struct.ImportSpecials* @"??0ImportSpecials@@QEAA@AEBU0@@Z"(%struct.ImportSpecials* returned, %struct.ImportSpecials* dereferenceable({{[0-9]+}}))
+ // G32-DAG: declare dllimport x86_thiscallcc void @_ZN14ImportSpecialsC1ERKS_(%struct.ImportSpecials*, %struct.ImportSpecials* dereferenceable({{[0-9]+}}))
+ // G64-DAG: declare dllimport void @_ZN14ImportSpecialsC1ERKS_(%struct.ImportSpecials*, %struct.ImportSpecials* dereferenceable({{[0-9]+}}))
+ __declspec(dllimport) ImportSpecials(const ImportSpecials&);
+
+ // M32-DAG: declare dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportSpecials* @"??4ImportSpecials@@QAEAAU0@ABU0@@Z"(%struct.ImportSpecials*, %struct.ImportSpecials* dereferenceable({{[0-9]+}}))
+ // M64-DAG: declare dllimport dereferenceable({{[0-9]+}}) %struct.ImportSpecials* @"??4ImportSpecials@@QEAAAEAU0@AEBU0@@Z"(%struct.ImportSpecials*, %struct.ImportSpecials* dereferenceable({{[0-9]+}}))
+ // G32-DAG: declare dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportSpecials* @_ZN14ImportSpecialsaSERKS_(%struct.ImportSpecials*, %struct.ImportSpecials* dereferenceable({{[0-9]+}}))
+ // G64-DAG: declare dllimport dereferenceable({{[0-9]+}}) %struct.ImportSpecials* @_ZN14ImportSpecialsaSERKS_(%struct.ImportSpecials*, %struct.ImportSpecials* dereferenceable({{[0-9]+}}))
+ __declspec(dllimport) ImportSpecials& operator=(const ImportSpecials&);
+
+ // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportSpecials* @"??0ImportSpecials@@QAE@$$QAU0@@Z"(%struct.ImportSpecials* returned, %struct.ImportSpecials* dereferenceable({{[0-9]+}}))
+ // M64-DAG: declare dllimport %struct.ImportSpecials* @"??0ImportSpecials@@QEAA@$$QEAU0@@Z"(%struct.ImportSpecials* returned, %struct.ImportSpecials* dereferenceable({{[0-9]+}}))
+ // G32-DAG: declare dllimport x86_thiscallcc void @_ZN14ImportSpecialsC1EOS_(%struct.ImportSpecials*, %struct.ImportSpecials* dereferenceable({{[0-9]+}}))
+ // G64-DAG: declare dllimport void @_ZN14ImportSpecialsC1EOS_(%struct.ImportSpecials*, %struct.ImportSpecials* dereferenceable({{[0-9]+}}))
+ __declspec(dllimport) ImportSpecials(ImportSpecials&&);
+
+ // M32-DAG: declare dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportSpecials* @"??4ImportSpecials@@QAEAAU0@$$QAU0@@Z"(%struct.ImportSpecials*, %struct.ImportSpecials* dereferenceable({{[0-9]+}}))
+ // M64-DAG: declare dllimport dereferenceable({{[0-9]+}}) %struct.ImportSpecials* @"??4ImportSpecials@@QEAAAEAU0@$$QEAU0@@Z"(%struct.ImportSpecials*, %struct.ImportSpecials* dereferenceable({{[0-9]+}}))
+ // G32-DAG: declare dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportSpecials* @_ZN14ImportSpecialsaSEOS_(%struct.ImportSpecials*, %struct.ImportSpecials* dereferenceable({{[0-9]+}}))
+ // G64-DAG: declare dllimport dereferenceable({{[0-9]+}}) %struct.ImportSpecials* @_ZN14ImportSpecialsaSEOS_(%struct.ImportSpecials*, %struct.ImportSpecials* dereferenceable({{[0-9]+}}))
+ __declspec(dllimport) ImportSpecials& operator=(ImportSpecials&&);
+};
+USESPECIALS(ImportSpecials)
+
+
+// Export inline special member functions.
+struct ImportInlineSpecials {
+ // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportInlineSpecials* @"??0ImportInlineSpecials@@QAE@XZ"(%struct.ImportInlineSpecials* returned)
+ // M64-DAG: declare dllimport %struct.ImportInlineSpecials* @"??0ImportInlineSpecials@@QEAA@XZ"(%struct.ImportInlineSpecials* returned)
+ // G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN20ImportInlineSpecialsC1Ev(%struct.ImportInlineSpecials* %this)
+ // G64-DAG: define linkonce_odr dso_local void @_ZN20ImportInlineSpecialsC1Ev(%struct.ImportInlineSpecials* %this)
+ // MO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportInlineSpecials* @"??0ImportInlineSpecials@@QAE@XZ"(
+ // GO1-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN20ImportInlineSpecialsC1Ev(
+ __declspec(dllimport) ImportInlineSpecials() {}
+
+ // M32-DAG: declare dllimport x86_thiscallcc void @"??1ImportInlineSpecials@@QAE@XZ"(%struct.ImportInlineSpecials*)
+ // M64-DAG: declare dllimport void @"??1ImportInlineSpecials@@QEAA@XZ"(%struct.ImportInlineSpecials*)
+ // G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN20ImportInlineSpecialsD1Ev(%struct.ImportInlineSpecials* %this)
+ // G64-DAG: define linkonce_odr dso_local void @_ZN20ImportInlineSpecialsD1Ev(%struct.ImportInlineSpecials* %this)
+ // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"??1ImportInlineSpecials@@QAE@XZ"(
+ // GO1-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN20ImportInlineSpecialsD1Ev(
+ __declspec(dllimport) ~ImportInlineSpecials() {}
+
+ // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportInlineSpecials* @"??0ImportInlineSpecials@@QAE@ABU0@@Z"(%struct.ImportInlineSpecials* returned, %struct.ImportInlineSpecials* dereferenceable({{[0-9]+}}))
+ // M64-DAG: declare dllimport %struct.ImportInlineSpecials* @"??0ImportInlineSpecials@@QEAA@AEBU0@@Z"(%struct.ImportInlineSpecials* returned, %struct.ImportInlineSpecials* dereferenceable({{[0-9]+}}))
+ // G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN20ImportInlineSpecialsC1ERKS_(%struct.ImportInlineSpecials* %this, %struct.ImportInlineSpecials* dereferenceable({{[0-9]+}}))
+ // G64-DAG: define linkonce_odr dso_local void @_ZN20ImportInlineSpecialsC1ERKS_(%struct.ImportInlineSpecials* %this, %struct.ImportInlineSpecials* dereferenceable({{[0-9]+}}))
+ // MO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportInlineSpecials* @"??0ImportInlineSpecials@@QAE@ABU0@@Z"(
+ // GO1-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN20ImportInlineSpecialsC1ERKS_(
+ __declspec(dllimport) inline ImportInlineSpecials(const ImportInlineSpecials&);
+
+ // M32-DAG: declare dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportInlineSpecials* @"??4ImportInlineSpecials@@QAEAAU0@ABU0@@Z"(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials* dereferenceable({{[0-9]+}}))
+ // M64-DAG: declare dllimport dereferenceable({{[0-9]+}}) %struct.ImportInlineSpecials* @"??4ImportInlineSpecials@@QEAAAEAU0@AEBU0@@Z"(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials* dereferenceable({{[0-9]+}}))
+ // G32-DAG: define linkonce_odr dso_local x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportInlineSpecials* @_ZN20ImportInlineSpecialsaSERKS_(%struct.ImportInlineSpecials* %this, %struct.ImportInlineSpecials* dereferenceable({{[0-9]+}}))
+ // G64-DAG: define linkonce_odr dso_local dereferenceable({{[0-9]+}}) %struct.ImportInlineSpecials* @_ZN20ImportInlineSpecialsaSERKS_(%struct.ImportInlineSpecials* %this, %struct.ImportInlineSpecials* dereferenceable({{[0-9]+}}))
+ // MO1-DAG: define available_externally dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportInlineSpecials* @"??4ImportInlineSpecials@@QAEAAU0@ABU0@@Z"(
+ // GO1-DAG: define linkonce_odr dso_local x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportInlineSpecials* @_ZN20ImportInlineSpecialsaSERKS_(
+ __declspec(dllimport) ImportInlineSpecials& operator=(const ImportInlineSpecials&);
+
+ // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportInlineSpecials* @"??0ImportInlineSpecials@@QAE@$$QAU0@@Z"(%struct.ImportInlineSpecials* returned, %struct.ImportInlineSpecials* dereferenceable({{[0-9]+}}))
+ // M64-DAG: declare dllimport %struct.ImportInlineSpecials* @"??0ImportInlineSpecials@@QEAA@$$QEAU0@@Z"(%struct.ImportInlineSpecials* returned, %struct.ImportInlineSpecials* dereferenceable({{[0-9]+}}))
+ // G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN20ImportInlineSpecialsC1EOS_(%struct.ImportInlineSpecials* %this, %struct.ImportInlineSpecials* dereferenceable({{[0-9]+}}))
+ // G64-DAG: define linkonce_odr dso_local void @_ZN20ImportInlineSpecialsC1EOS_(%struct.ImportInlineSpecials* %this, %struct.ImportInlineSpecials* dereferenceable({{[0-9]+}}))
+ // MO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportInlineSpecials* @"??0ImportInlineSpecials@@QAE@$$QAU0@@Z"(
+ // GO1-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN20ImportInlineSpecialsC1EOS_(
+ __declspec(dllimport) ImportInlineSpecials(ImportInlineSpecials&&) {}
+
+ // M32-DAG: declare dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportInlineSpecials* @"??4ImportInlineSpecials@@QAEAAU0@$$QAU0@@Z"(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials* dereferenceable({{[0-9]+}}))
+ // M64-DAG: declare dllimport dereferenceable({{[0-9]+}}) %struct.ImportInlineSpecials* @"??4ImportInlineSpecials@@QEAAAEAU0@$$QEAU0@@Z"(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials* dereferenceable({{[0-9]+}}))
+ // G32-DAG: define linkonce_odr dso_local x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportInlineSpecials* @_ZN20ImportInlineSpecialsaSEOS_(%struct.ImportInlineSpecials* %this, %struct.ImportInlineSpecials* dereferenceable({{[0-9]+}}))
+ // G64-DAG: define linkonce_odr dso_local dereferenceable({{[0-9]+}}) %struct.ImportInlineSpecials* @_ZN20ImportInlineSpecialsaSEOS_(%struct.ImportInlineSpecials* %this, %struct.ImportInlineSpecials* dereferenceable({{[0-9]+}}))
+ // MO1-DAG: define available_externally dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportInlineSpecials* @"??4ImportInlineSpecials@@QAEAAU0@$$QAU0@@Z"(
+ // GO1-DAG: define linkonce_odr dso_local x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportInlineSpecials* @_ZN20ImportInlineSpecialsaSEOS_(
+ __declspec(dllimport) ImportInlineSpecials& operator=(ImportInlineSpecials&&) { return *this; }
+};
+ImportInlineSpecials::ImportInlineSpecials(const ImportInlineSpecials&) {}
+inline ImportInlineSpecials& ImportInlineSpecials::operator=(const ImportInlineSpecials&) { return *this; }
+USESPECIALS(ImportInlineSpecials)
+
+
+// Import defaulted member functions.
+struct ImportDefaulted {
+ // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportDefaulted* @"??0ImportDefaulted@@QAE@XZ"(%struct.ImportDefaulted* returned)
+ // M64-DAG: declare dllimport %struct.ImportDefaulted* @"??0ImportDefaulted@@QEAA@XZ"(%struct.ImportDefaulted* returned)
+ // G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN15ImportDefaultedC1Ev(%struct.ImportDefaulted* %this)
+ // G64-DAG: define linkonce_odr dso_local void @_ZN15ImportDefaultedC1Ev(%struct.ImportDefaulted* %this)
+ // MO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportDefaulted* @"??0ImportDefaulted@@QAE@XZ"(%struct.ImportDefaulted* returned %this)
+ // GO1-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN15ImportDefaultedC1Ev(%struct.ImportDefaulted* %this)
+ __declspec(dllimport) ImportDefaulted() = default;
+
+ // M32-DAG: declare dllimport x86_thiscallcc void @"??1ImportDefaulted@@QAE@XZ"(%struct.ImportDefaulted*)
+ // M64-DAG: declare dllimport void @"??1ImportDefaulted@@QEAA@XZ"(%struct.ImportDefaulted*)
+ // G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN15ImportDefaultedD1Ev(%struct.ImportDefaulted* %this)
+ // G64-DAG: define linkonce_odr dso_local void @_ZN15ImportDefaultedD1Ev(%struct.ImportDefaulted* %this)
+ // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"??1ImportDefaulted@@QAE@XZ"(%struct.ImportDefaulted* %this)
+ // GO1-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN15ImportDefaultedD1Ev(%struct.ImportDefaulted* %this)
+ __declspec(dllimport) ~ImportDefaulted() = default;
+
+ // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportDefaulted* @"??0ImportDefaulted@@QAE@ABU0@@Z"(%struct.ImportDefaulted* returned, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+ // M64-DAG: declare dllimport %struct.ImportDefaulted* @"??0ImportDefaulted@@QEAA@AEBU0@@Z"(%struct.ImportDefaulted* returned, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+ // G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN15ImportDefaultedC1ERKS_(%struct.ImportDefaulted* %this, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+ // G64-DAG: define linkonce_odr dso_local void @_ZN15ImportDefaultedC1ERKS_(%struct.ImportDefaulted* %this, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+ // MO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportDefaulted* @"??0ImportDefaulted@@QAE@ABU0@@Z"(%struct.ImportDefaulted* returned %this, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+ // GO1-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN15ImportDefaultedC1ERKS_(%struct.ImportDefaulted* %this, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+ __declspec(dllimport) ImportDefaulted(const ImportDefaulted&) = default;
+
+ // M32-DAG: declare dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportDefaulted* @"??4ImportDefaulted@@QAEAAU0@ABU0@@Z"(%struct.ImportDefaulted*, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+ // M64-DAG: declare dllimport dereferenceable({{[0-9]+}}) %struct.ImportDefaulted* @"??4ImportDefaulted@@QEAAAEAU0@AEBU0@@Z"(%struct.ImportDefaulted*, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+ // G32-DAG: define linkonce_odr dso_local x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportDefaulted* @_ZN15ImportDefaultedaSERKS_(%struct.ImportDefaulted* %this, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+ // G64-DAG: define linkonce_odr dso_local dereferenceable({{[0-9]+}}) %struct.ImportDefaulted* @_ZN15ImportDefaultedaSERKS_(%struct.ImportDefaulted* %this, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+ // MO1-DAG: define available_externally dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportDefaulted* @"??4ImportDefaulted@@QAEAAU0@ABU0@@Z"(%struct.ImportDefaulted* %this, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+ // GO1-DAG: define linkonce_odr dso_local x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportDefaulted* @_ZN15ImportDefaultedaSERKS_(%struct.ImportDefaulted* %this, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+ __declspec(dllimport) ImportDefaulted& operator=(const ImportDefaulted&) = default;
+
+ // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportDefaulted* @"??0ImportDefaulted@@QAE@$$QAU0@@Z"(%struct.ImportDefaulted* returned, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+ // M64-DAG: declare dllimport %struct.ImportDefaulted* @"??0ImportDefaulted@@QEAA@$$QEAU0@@Z"(%struct.ImportDefaulted* returned, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+ // G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN15ImportDefaultedC1EOS_(%struct.ImportDefaulted* %this, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+ // G64-DAG: define linkonce_odr dso_local void @_ZN15ImportDefaultedC1EOS_(%struct.ImportDefaulted* %this, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+ // MO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportDefaulted* @"??0ImportDefaulted@@QAE@$$QAU0@@Z"(%struct.ImportDefaulted* returned %this, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+ // GO1-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN15ImportDefaultedC1EOS_(%struct.ImportDefaulted* %this, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+ __declspec(dllimport) ImportDefaulted(ImportDefaulted&&) = default;
+
+ // M32-DAG: declare dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportDefaulted* @"??4ImportDefaulted@@QAEAAU0@$$QAU0@@Z"(%struct.ImportDefaulted*, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+ // M64-DAG: declare dllimport dereferenceable({{[0-9]+}}) %struct.ImportDefaulted* @"??4ImportDefaulted@@QEAAAEAU0@$$QEAU0@@Z"(%struct.ImportDefaulted*, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+ // G32-DAG: define linkonce_odr dso_local x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportDefaulted* @_ZN15ImportDefaultedaSEOS_(%struct.ImportDefaulted* %this, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+ // G64-DAG: define linkonce_odr dso_local dereferenceable({{[0-9]+}}) %struct.ImportDefaulted* @_ZN15ImportDefaultedaSEOS_(%struct.ImportDefaulted* %this, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+ // MO1-DAG: define available_externally dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportDefaulted* @"??4ImportDefaulted@@QAEAAU0@$$QAU0@@Z"(%struct.ImportDefaulted* %this, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+ // GO1-DAG: define linkonce_odr dso_local x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportDefaulted* @_ZN15ImportDefaultedaSEOS_(%struct.ImportDefaulted* %this, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+ __declspec(dllimport) ImportDefaulted& operator=(ImportDefaulted&&) = default;
+
+ ForceNonTrivial v; // ensure special members are non-trivial
+};
+USESPECIALS(ImportDefaulted)
+
+
+// Import defaulted member function definitions.
+struct ImportDefaultedDefs {
+ __declspec(dllimport) inline ImportDefaultedDefs();
+ __declspec(dllimport) inline ~ImportDefaultedDefs();
+
+ __declspec(dllimport) ImportDefaultedDefs(const ImportDefaultedDefs&);
+ __declspec(dllimport) ImportDefaultedDefs& operator=(const ImportDefaultedDefs&);
+
+ __declspec(dllimport) ImportDefaultedDefs(ImportDefaultedDefs&&);
+ __declspec(dllimport) ImportDefaultedDefs& operator=(ImportDefaultedDefs&&);
+};
+
+#ifdef MSABI
+// For MinGW, the function will not be dllimport, and we cannot add the attribute now.
+// M32-DAG: declare dllimport x86_thiscallcc %struct.ImportDefaultedDefs* @"??0ImportDefaultedDefs@@QAE@XZ"(%struct.ImportDefaultedDefs* returned)
+// M64-DAG: declare dllimport %struct.ImportDefaultedDefs* @"??0ImportDefaultedDefs@@QEAA@XZ"(%struct.ImportDefaultedDefs* returned)
+__declspec(dllimport) ImportDefaultedDefs::ImportDefaultedDefs() = default;
+#endif
+
+#ifdef MSABI
+// For MinGW, the function will not be dllimport, and we cannot add the attribute now.
+// M32-DAG: declare dllimport x86_thiscallcc void @"??1ImportDefaultedDefs@@QAE@XZ"(%struct.ImportDefaultedDefs*)
+// M64-DAG: declare dllimport void @"??1ImportDefaultedDefs@@QEAA@XZ"(%struct.ImportDefaultedDefs*)
+__declspec(dllimport) ImportDefaultedDefs::~ImportDefaultedDefs() = default;
+#endif
+
+// M32-DAG: declare dllimport x86_thiscallcc %struct.ImportDefaultedDefs* @"??0ImportDefaultedDefs@@QAE@ABU0@@Z"(%struct.ImportDefaultedDefs* returned, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// M64-DAG: declare dllimport %struct.ImportDefaultedDefs* @"??0ImportDefaultedDefs@@QEAA@AEBU0@@Z"(%struct.ImportDefaultedDefs* returned, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN19ImportDefaultedDefsC1ERKS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// G64-DAG: define linkonce_odr dso_local void @_ZN19ImportDefaultedDefsC1ERKS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
+inline ImportDefaultedDefs::ImportDefaultedDefs(const ImportDefaultedDefs&) = default;
+
+// M32-DAG: declare dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportDefaultedDefs* @"??4ImportDefaultedDefs@@QAEAAU0@ABU0@@Z"(%struct.ImportDefaultedDefs*, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// M64-DAG: declare dllimport dereferenceable({{[0-9]+}}) %struct.ImportDefaultedDefs* @"??4ImportDefaultedDefs@@QEAAAEAU0@AEBU0@@Z"(%struct.ImportDefaultedDefs*, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// G32-DAG: define linkonce_odr dso_local x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportDefaultedDefs* @_ZN19ImportDefaultedDefsaSERKS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// G64-DAG: define linkonce_odr dso_local dereferenceable({{[0-9]+}}) %struct.ImportDefaultedDefs* @_ZN19ImportDefaultedDefsaSERKS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
+inline ImportDefaultedDefs& ImportDefaultedDefs::operator=(const ImportDefaultedDefs&) = default;
+
+// M32-DAG: define dso_local dllexport x86_thiscallcc %struct.ImportDefaultedDefs* @"??0ImportDefaultedDefs@@QAE@$$QAU0@@Z"(%struct.ImportDefaultedDefs* returned %this, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// M64-DAG: define dso_local dllexport %struct.ImportDefaultedDefs* @"??0ImportDefaultedDefs@@QEAA@$$QEAU0@@Z"(%struct.ImportDefaultedDefs* returned %this, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// G32-DAG: define dso_local x86_thiscallcc void @_ZN19ImportDefaultedDefsC1EOS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// G64-DAG: define dso_local void @_ZN19ImportDefaultedDefsC1EOS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// G32-DAG: define dso_local x86_thiscallcc void @_ZN19ImportDefaultedDefsC2EOS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// G64-DAG: define dso_local void @_ZN19ImportDefaultedDefsC2EOS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
+ImportDefaultedDefs::ImportDefaultedDefs(ImportDefaultedDefs&&) = default; // dllimport ignored
+
+// M32-DAG: define dso_local dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportDefaultedDefs* @"??4ImportDefaultedDefs@@QAEAAU0@$$QAU0@@Z"(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// M64-DAG: define dso_local dllexport dereferenceable({{[0-9]+}}) %struct.ImportDefaultedDefs* @"??4ImportDefaultedDefs@@QEAAAEAU0@$$QEAU0@@Z"(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// G32-DAG: define dso_local x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportDefaultedDefs* @_ZN19ImportDefaultedDefsaSEOS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// G64-DAG: define dso_local dereferenceable({{[0-9]+}}) %struct.ImportDefaultedDefs* @_ZN19ImportDefaultedDefsaSEOS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
+ImportDefaultedDefs& ImportDefaultedDefs::operator=(ImportDefaultedDefs&&) = default; // dllimport ignored
+
+USESPECIALS(ImportDefaultedDefs)
+
+
+// Import allocation functions.
+struct ImportAlloc {
+ __declspec(dllimport) void* operator new(__SIZE_TYPE__);
+ __declspec(dllimport) void* operator new[](__SIZE_TYPE__);
+ __declspec(dllimport) void operator delete(void*);
+ __declspec(dllimport) void operator delete[](void*);
+};
+
+// M32-DAG: declare dllimport i8* @"??2ImportAlloc@@SAPAXI@Z"(i32)
+// M64-DAG: declare dllimport i8* @"??2ImportAlloc@@SAPEAX_K@Z"(i64)
+// G32-DAG: declare dllimport i8* @_ZN11ImportAllocnwEj(i32)
+// G64-DAG: declare dllimport i8* @_ZN11ImportAllocnwEy(i64)
+void UNIQ(use)() { new ImportAlloc(); }
+
+// M32-DAG: declare dllimport i8* @"??_UImportAlloc@@SAPAXI@Z"(i32)
+// M64-DAG: declare dllimport i8* @"??_UImportAlloc@@SAPEAX_K@Z"(i64)
+// G32-DAG: declare dllimport i8* @_ZN11ImportAllocnaEj(i32)
+// G64-DAG: declare dllimport i8* @_ZN11ImportAllocnaEy(i64)
+void UNIQ(use)() { new ImportAlloc[1]; }
+
+// M32-DAG: declare dllimport void @"??3ImportAlloc@@SAXPAX@Z"(i8*)
+// M64-DAG: declare dllimport void @"??3ImportAlloc@@SAXPEAX@Z"(i8*)
+// G32-DAG: declare dllimport void @_ZN11ImportAllocdlEPv(i8*)
+// G64-DAG: declare dllimport void @_ZN11ImportAllocdlEPv(i8*)
+void UNIQ(use)(ImportAlloc* ptr) { delete ptr; }
+
+// M32-DAG: declare dllimport void @"??_VImportAlloc@@SAXPAX@Z"(i8*)
+// M64-DAG: declare dllimport void @"??_VImportAlloc@@SAXPEAX@Z"(i8*)
+// G32-DAG: declare dllimport void @_ZN11ImportAllocdaEPv(i8*)
+// G64-DAG: declare dllimport void @_ZN11ImportAllocdaEPv(i8*)
+void UNIQ(use)(ImportAlloc* ptr) { delete[] ptr; }
+
+
+//===----------------------------------------------------------------------===//
+// Class member templates
+//===----------------------------------------------------------------------===//
+
+struct MemFunTmpl {
+ template<typename T> void normalDef() {}
+ template<typename T> __declspec(dllimport) void importedNormal() {}
+ template<typename T> static void staticDef() {}
+ template<typename T> __declspec(dllimport) static void importedStatic() {}
+};
+
+// Import implicit instantiation of an imported member function template.
+// M32-DAG: declare dllimport x86_thiscallcc void @"??$importedNormal@UImplicitInst_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*)
+// M64-DAG: declare dllimport void @"??$importedNormal@UImplicitInst_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*)
+// G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN10MemFunTmpl14importedNormalI21ImplicitInst_ImportedEEvv(%struct.MemFunTmpl* %this)
+// G64-DAG: define linkonce_odr dso_local void @_ZN10MemFunTmpl14importedNormalI21ImplicitInst_ImportedEEvv(%struct.MemFunTmpl* %this)
+USEMF(MemFunTmpl, importedNormal<ImplicitInst_Imported>)
+
+// MSC-DAG: declare dllimport void @"??$importedStatic@UImplicitInst_Imported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: define linkonce_odr dso_local void @_ZN10MemFunTmpl14importedStaticI21ImplicitInst_ImportedEEvv()
+USE(MemFunTmpl::importedStatic<ImplicitInst_Imported>)
+
+
+// Import explicit instantiation declaration of an imported member function
+// template.
+// M32-DAG: declare dllimport x86_thiscallcc void @"??$importedNormal@UExplicitDecl_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*)
+// M64-DAG: declare dllimport void @"??$importedNormal@UExplicitDecl_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*)
+// G32-DAG: declare dso_local x86_thiscallcc void @_ZN10MemFunTmpl14importedNormalI21ExplicitDecl_ImportedEEvv(%struct.MemFunTmpl*)
+// G64-DAG: declare dso_local void @_ZN10MemFunTmpl14importedNormalI21ExplicitDecl_ImportedEEvv(%struct.MemFunTmpl*)
+extern template void MemFunTmpl::importedNormal<ExplicitDecl_Imported>();
+USEMF(MemFunTmpl, importedNormal<ExplicitDecl_Imported>)
+
+// MSC-DAG: declare dllimport void @"??$importedStatic@UExplicitDecl_Imported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: declare dso_local void @_ZN10MemFunTmpl14importedStaticI21ExplicitDecl_ImportedEEvv()
+extern template void MemFunTmpl::importedStatic<ExplicitDecl_Imported>();
+USE(MemFunTmpl::importedStatic<ExplicitDecl_Imported>)
+
+
+// Import explicit instantiation definition of an imported member function
+// template.
+// M32-DAG: declare dllimport x86_thiscallcc void @"??$importedNormal@UExplicitInst_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*)
+// M64-DAG: declare dllimport void @"??$importedNormal@UExplicitInst_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*)
+// G32-DAG: define weak_odr dso_local x86_thiscallcc void @_ZN10MemFunTmpl14importedNormalI21ExplicitInst_ImportedEEvv(%struct.MemFunTmpl* %this)
+// G64-DAG: define weak_odr dso_local void @_ZN10MemFunTmpl14importedNormalI21ExplicitInst_ImportedEEvv(%struct.MemFunTmpl* %this)
+template void MemFunTmpl::importedNormal<ExplicitInst_Imported>();
+USEMF(MemFunTmpl, importedNormal<ExplicitInst_Imported>)
+
+// MSC-DAG: declare dllimport void @"??$importedStatic@UExplicitInst_Imported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: define weak_odr dso_local void @_ZN10MemFunTmpl14importedStaticI21ExplicitInst_ImportedEEvv()
+template void MemFunTmpl::importedStatic<ExplicitInst_Imported>();
+USE(MemFunTmpl::importedStatic<ExplicitInst_Imported>)
+
+
+// Import specialization of an imported member function template.
+// M32-DAG: declare dllimport x86_thiscallcc void @"??$importedNormal@UExplicitSpec_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*)
+// M64-DAG: declare dllimport void @"??$importedNormal@UExplicitSpec_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*)
+// G32-DAG: declare dllimport x86_thiscallcc void @_ZN10MemFunTmpl14importedNormalI21ExplicitSpec_ImportedEEvv(%struct.MemFunTmpl*)
+// G64-DAG: declare dllimport void @_ZN10MemFunTmpl14importedNormalI21ExplicitSpec_ImportedEEvv(%struct.MemFunTmpl*)
+template<> __declspec(dllimport) void MemFunTmpl::importedNormal<ExplicitSpec_Imported>();
+USEMF(MemFunTmpl, importedNormal<ExplicitSpec_Imported>)
+
+// M32-DAG-FIXME: declare dllimport x86_thiscallcc void @"??$importedNormal@UExplicitSpec_Def_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*)
+// M64-DAG-FIXME: declare dllimport void @"??$importedNormal@UExplicitSpec_Def_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*)
+#ifdef MSABI
+//template<> __declspec(dllimport) void MemFunTmpl::importedNormal<ExplicitSpec_Def_Imported>() {}
+//USEMF(MemFunTmpl, importedNormal<ExplicitSpec_Def_Imported>)
+#endif
+
+// M32-DAG: declare dllimport x86_thiscallcc void @"??$importedNormal@UExplicitSpec_InlineDef_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*)
+// M64-DAG: declare dllimport void @"??$importedNormal@UExplicitSpec_InlineDef_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*)
+// G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN10MemFunTmpl14importedNormalI31ExplicitSpec_InlineDef_ImportedEEvv(%struct.MemFunTmpl* %this)
+// G64-DAG: define linkonce_odr dso_local void @_ZN10MemFunTmpl14importedNormalI31ExplicitSpec_InlineDef_ImportedEEvv(%struct.MemFunTmpl* %this)
+template<> __declspec(dllimport) inline void MemFunTmpl::importedNormal<ExplicitSpec_InlineDef_Imported>() {}
+USEMF(MemFunTmpl, importedNormal<ExplicitSpec_InlineDef_Imported>)
+
+
+// MSC-DAG: declare dllimport void @"??$importedStatic@UExplicitSpec_Imported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: declare dllimport void @_ZN10MemFunTmpl14importedStaticI21ExplicitSpec_ImportedEEvv()
+template<> __declspec(dllimport) void MemFunTmpl::importedStatic<ExplicitSpec_Imported>();
+USE(MemFunTmpl::importedStatic<ExplicitSpec_Imported>)
+
+// MSC-DAG-FIXME: declare dllimport void @"??$importedStatic@UExplicitSpec_Def_Imported@@@MemFunTmpl@@SAXXZ"()
+#ifdef MSABI
+//template<> __declspec(dllimport) void MemFunTmpl::importedStatic<ExplicitSpec_Def_Imported>() {}
+//USE(MemFunTmpl::importedStatic<ExplicitSpec_Def_Imported>)
+#endif
+
+// MSC-DAG: declare dllimport void @"??$importedStatic@UExplicitSpec_InlineDef_Imported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: define linkonce_odr dso_local void @_ZN10MemFunTmpl14importedStaticI31ExplicitSpec_InlineDef_ImportedEEvv()
+template<> __declspec(dllimport) inline void MemFunTmpl::importedStatic<ExplicitSpec_InlineDef_Imported>() {}
+USE(MemFunTmpl::importedStatic<ExplicitSpec_InlineDef_Imported>)
+
+
+// Not importing specialization of an imported member function template without
+// explicit dllimport.
+// M32-DAG: define dso_local x86_thiscallcc void @"??$importedNormal@UExplicitSpec_NotImported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl* %this)
+// M64-DAG: define dso_local void @"??$importedNormal@UExplicitSpec_NotImported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl* %this)
+// G32-DAG: define dso_local x86_thiscallcc void @_ZN10MemFunTmpl14importedNormalI24ExplicitSpec_NotImportedEEvv(%struct.MemFunTmpl* %this)
+// G64-DAG: define dso_local void @_ZN10MemFunTmpl14importedNormalI24ExplicitSpec_NotImportedEEvv(%struct.MemFunTmpl* %this)
+template<> void MemFunTmpl::importedNormal<ExplicitSpec_NotImported>() {}
+USEMF(MemFunTmpl, importedNormal<ExplicitSpec_NotImported>)
+
+// MSC-DAG: define dso_local void @"??$importedStatic@UExplicitSpec_NotImported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: define dso_local void @_ZN10MemFunTmpl14importedStaticI24ExplicitSpec_NotImportedEEvv()
+template<> void MemFunTmpl::importedStatic<ExplicitSpec_NotImported>() {}
+USE(MemFunTmpl::importedStatic<ExplicitSpec_NotImported>)
+
+
+// Import explicit instantiation declaration of a non-imported member function
+// template.
+// M32-DAG: declare dllimport x86_thiscallcc void @"??$normalDef@UExplicitDecl_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*)
+// M64-DAG: declare dllimport void @"??$normalDef@UExplicitDecl_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*)
+// G32-DAG: declare dso_local x86_thiscallcc void @_ZN10MemFunTmpl9normalDefI21ExplicitDecl_ImportedEEvv(%struct.MemFunTmpl*)
+// G64-DAG: declare dso_local void @_ZN10MemFunTmpl9normalDefI21ExplicitDecl_ImportedEEvv(%struct.MemFunTmpl*)
+extern template __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitDecl_Imported>();
+USEMF(MemFunTmpl, normalDef<ExplicitDecl_Imported>)
+
+// MSC-DAG: declare dllimport void @"??$staticDef@UExplicitDecl_Imported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: declare dso_local void @_ZN10MemFunTmpl9staticDefI21ExplicitDecl_ImportedEEvv()
+extern template __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitDecl_Imported>();
+USE(MemFunTmpl::staticDef<ExplicitDecl_Imported>)
+
+
+// Import explicit instantiation definition of a non-imported member function
+// template.
+// M32-DAG: declare dllimport x86_thiscallcc void @"??$normalDef@UExplicitInst_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*)
+// M64-DAG: declare dllimport void @"??$normalDef@UExplicitInst_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*)
+// G32-DAG: define weak_odr dso_local x86_thiscallcc void @_ZN10MemFunTmpl9normalDefI21ExplicitInst_ImportedEEvv(%struct.MemFunTmpl* %this)
+// G64-DAG: define weak_odr dso_local void @_ZN10MemFunTmpl9normalDefI21ExplicitInst_ImportedEEvv(%struct.MemFunTmpl* %this)
+template __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitInst_Imported>();
+USEMF(MemFunTmpl, normalDef<ExplicitInst_Imported>)
+
+// MSC-DAG: declare dllimport void @"??$staticDef@UExplicitInst_Imported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: define weak_odr dso_local void @_ZN10MemFunTmpl9staticDefI21ExplicitInst_ImportedEEvv()
+template __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitInst_Imported>();
+USE(MemFunTmpl::staticDef<ExplicitInst_Imported>)
+
+
+// Import specialization of a non-imported member function template.
+// M32-DAG: declare dllimport x86_thiscallcc void @"??$normalDef@UExplicitSpec_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*)
+// M64-DAG: declare dllimport void @"??$normalDef@UExplicitSpec_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*)
+// G32-DAG: declare dllimport x86_thiscallcc void @_ZN10MemFunTmpl9normalDefI21ExplicitSpec_ImportedEEvv(%struct.MemFunTmpl*)
+// G64-DAG: declare dllimport void @_ZN10MemFunTmpl9normalDefI21ExplicitSpec_ImportedEEvv(%struct.MemFunTmpl*)
+template<> __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitSpec_Imported>();
+USEMF(MemFunTmpl, normalDef<ExplicitSpec_Imported>)
+
+// M32-DAG-FIXME: declare dllimport x86_thiscallcc void @"??$normalDef@UExplicitSpec_Def_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*)
+// M64-DAG-FIXME: declare dllimport void @"??$normalDef@UExplicitSpec_Def_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*)
+#ifdef MSABI
+//template<> __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitSpec_Def_Imported>() {}
+//USEMF(MemFunTmpl, normalDef<ExplicitSpec_Def_Imported>)
+#endif
+
+// M32-DAG: declare dllimport x86_thiscallcc void @"??$normalDef@UExplicitSpec_InlineDef_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*)
+// M64-DAG: declare dllimport void @"??$normalDef@UExplicitSpec_InlineDef_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*)
+// G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN10MemFunTmpl9normalDefI31ExplicitSpec_InlineDef_ImportedEEvv(%struct.MemFunTmpl* %this)
+// G64-DAG: define linkonce_odr dso_local void @_ZN10MemFunTmpl9normalDefI31ExplicitSpec_InlineDef_ImportedEEvv(%struct.MemFunTmpl* %this)
+template<> __declspec(dllimport) inline void MemFunTmpl::normalDef<ExplicitSpec_InlineDef_Imported>() {}
+USEMF(MemFunTmpl, normalDef<ExplicitSpec_InlineDef_Imported>)
+
+
+// MSC-DAG: declare dllimport void @"??$staticDef@UExplicitSpec_Imported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: declare dllimport void @_ZN10MemFunTmpl9staticDefI21ExplicitSpec_ImportedEEvv()
+template<> __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitSpec_Imported>();
+USE(MemFunTmpl::staticDef<ExplicitSpec_Imported>)
+
+// MSC-DAG-FIXME: declare dllimport void @"??$staticDef@UExplicitSpec_Def_Imported@@@MemFunTmpl@@SAXXZ"()
+#ifdef MSABI
+//template<> __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitSpec_Def_Imported>() {}
+//USE(MemFunTmpl::staticDef<ExplicitSpec_Def_Imported>)
+#endif
+
+// MSC-DAG: declare dllimport void @"??$staticDef@UExplicitSpec_InlineDef_Imported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: define linkonce_odr dso_local void @_ZN10MemFunTmpl9staticDefI31ExplicitSpec_InlineDef_ImportedEEvv()
+template<> __declspec(dllimport) inline void MemFunTmpl::staticDef<ExplicitSpec_InlineDef_Imported>() {}
+USE(MemFunTmpl::staticDef<ExplicitSpec_InlineDef_Imported>)
+
+
+
+struct MemVarTmpl {
+ template<typename T> static const int StaticVar = 1;
+ template<typename T> __declspec(dllimport) static const int ImportedStaticVar = 1;
+};
+
+// Import implicit instantiation of an imported member variable template.
+// MSC-DAG: @"??$ImportedStaticVar@UImplicitInst_Imported@@@MemVarTmpl@@2HB" = available_externally dllimport constant i32 1, align 4
+// GNU-DAG: @_ZN10MemVarTmpl17ImportedStaticVarI21ImplicitInst_ImportedEE = external dllimport constant i32
+USEMV(MemVarTmpl, ImportedStaticVar<ImplicitInst_Imported>)
+
+// Import explicit instantiation declaration of an imported member variable
+// template.
+// MSC-DAG: @"??$ImportedStaticVar@UExplicitDecl_Imported@@@MemVarTmpl@@2HB" = available_externally dllimport constant i32 1
+// GNU-DAG: @_ZN10MemVarTmpl17ImportedStaticVarI21ExplicitDecl_ImportedEE = external dllimport constant i32
+extern template const int MemVarTmpl::ImportedStaticVar<ExplicitDecl_Imported>;
+USEMV(MemVarTmpl, ImportedStaticVar<ExplicitDecl_Imported>)
+
+// An explicit instantiation definition of an imported member variable template
+// cannot be imported because the template must be defined which is illegal. The
+// in-class initializer does not count.
+
+// Import specialization of an imported member variable template.
+// MSC-DAG: @"??$ImportedStaticVar@UExplicitSpec_Imported@@@MemVarTmpl@@2HB" = external dllimport constant i32
+// GNU-DAG: @_ZN10MemVarTmpl17ImportedStaticVarI21ExplicitSpec_ImportedEE = external dllimport constant i32
+template<> __declspec(dllimport) const int MemVarTmpl::ImportedStaticVar<ExplicitSpec_Imported>;
+USEMV(MemVarTmpl, ImportedStaticVar<ExplicitSpec_Imported>)
+
+// Not importing specialization of a member variable template without explicit
+// dllimport.
+// MSC-DAG: @"??$ImportedStaticVar@UExplicitSpec_NotImported@@@MemVarTmpl@@2HB" = external dso_local constant i32
+// GNU-DAG: @_ZN10MemVarTmpl17ImportedStaticVarI24ExplicitSpec_NotImportedEE = external constant i32
+template<> const int MemVarTmpl::ImportedStaticVar<ExplicitSpec_NotImported>;
+USEMV(MemVarTmpl, ImportedStaticVar<ExplicitSpec_NotImported>)
+
+
+// Import explicit instantiation declaration of a non-imported member variable
+// template.
+// MSC-DAG: @"??$StaticVar@UExplicitDecl_Imported@@@MemVarTmpl@@2HB" = available_externally dllimport constant i32 1
+// GNU-DAG: @_ZN10MemVarTmpl9StaticVarI21ExplicitDecl_ImportedEE = external dllimport constant i32
+extern template __declspec(dllimport) const int MemVarTmpl::StaticVar<ExplicitDecl_Imported>;
+USEMV(MemVarTmpl, StaticVar<ExplicitDecl_Imported>)
+
+// An explicit instantiation definition of a non-imported member variable template
+// cannot be imported because the template must be defined which is illegal. The
+// in-class initializer does not count.
+
+// Import specialization of a non-imported member variable template.
+// MSC-DAG: @"??$StaticVar@UExplicitSpec_Imported@@@MemVarTmpl@@2HB" = external dllimport constant i32
+// GNU-DAG: @_ZN10MemVarTmpl9StaticVarI21ExplicitSpec_ImportedEE = external dllimport constant i32
+template<> __declspec(dllimport) const int MemVarTmpl::StaticVar<ExplicitSpec_Imported>;
+USEMV(MemVarTmpl, StaticVar<ExplicitSpec_Imported>)
diff --git a/src/llvm-project/clang/test/CodeGenCXX/dllimport-memptr-global.cpp b/src/llvm-project/clang/test/CodeGenCXX/dllimport-memptr-global.cpp
new file mode 100644
index 0000000..91abfeb
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/dllimport-memptr-global.cpp
@@ -0,0 +1,58 @@
+// Also check that -Wglobal-constructors does the right thing. Strictly
+// speaking, this is a Sema test, but this avoids test case duplication.
+// RUN: %clang_cc1 -Wglobal-constructors %s -verify -triple i686-windows-msvc -fms-extensions -std=c++11
+//
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple i686-windows-msvc -fms-extensions -std=c++11 | FileCheck %s
+
+struct __declspec(dllimport) Single {
+ void nonvirt();
+ virtual void virt();
+};
+
+struct A { int a; };
+struct B { int b; };
+struct __declspec(dllimport) Multi : A, B {
+ void nonvirt();
+ virtual void virt();
+};
+
+struct __declspec(dllimport) Virtual : virtual A {
+ void nonvirt();
+ virtual void virt();
+};
+
+struct General;
+static_assert(sizeof(void (General::*)()) == 16, "force general memptr model");
+struct __declspec(dllimport) General {
+ void nonvirt();
+ virtual void virt();
+};
+
+auto mp_single_nv = &Single::nonvirt; // expected-warning {{global constructor}}
+auto mp_multi_nv = &Multi::nonvirt; // expected-warning {{global constructor}}
+auto mp_virtual_nv = &Virtual::nonvirt; // expected-warning {{global constructor}}
+auto mp_general_nv = &General::nonvirt; // expected-warning {{global constructor}}
+
+auto mp_single_v = &Single::virt;
+auto mp_multi_v = &Multi::virt;
+auto mp_virtual_v = &Virtual::virt;
+auto mp_general_v = &General::virt;
+
+// All of the non-virtual globals need dynamic initializers.
+
+// CHECK: @"?mp_single_nv@@3P8Single@@AEXXZQ1@" = dso_local global i8* null, align 4
+// CHECK: @"?mp_multi_nv@@3P8Multi@@AEXXZQ1@" = dso_local global { i8*, i32 } zeroinitializer, align 4
+// CHECK: @"?mp_virtual_nv@@3P8Virtual@@AEXXZQ1@" = dso_local global { i8*, i32, i32 } zeroinitializer, align 4
+// CHECK: @"?mp_general_nv@@3P8General@@AEXXZQ1@" = dso_local global { i8*, i32, i32, i32 } zeroinitializer, align 4
+
+// CHECK: @"?mp_single_v@@3P8Single@@AEXXZQ1@" = dso_local global i8* bitcast (void (%struct.Single*, ...)* @"??_9Single@@$BA@AE" to i8*), align 4
+// CHECK: @"?mp_multi_v@@3P8Multi@@AEXXZQ1@" = dso_local global { i8*, i32 } { i8* bitcast (void (%struct.Multi*, ...)* @"??_9Multi@@$BA@AE" to i8*), i32 0 }, align 4
+// CHECK: @"?mp_virtual_v@@3P8Virtual@@AEXXZQ1@" = dso_local global { i8*, i32, i32 } { i8* bitcast (void (%struct.Virtual*, ...)* @"??_9Virtual@@$BA@AE" to i8*), i32 0, i32 0 }, align 4
+// CHECK: @"?mp_general_v@@3P8General@@AEXXZQ1@" = dso_local global { i8*, i32, i32, i32 } { i8* bitcast (void (%struct.General*, ...)* @"??_9General@@$BA@AE" to i8*), i32 0, i32 0, i32 0 }, align 4
+
+// CHECK: define internal void @_GLOBAL__sub_I{{.*}}() {{.*}} {
+// CHECK: call void @"??__Emp_single_nv@@YAXXZ"()
+// CHECK: call void @"??__Emp_multi_nv@@YAXXZ"()
+// CHECK: call void @"??__Emp_virtual_nv@@YAXXZ"()
+// CHECK: call void @"??__Emp_general_nv@@YAXXZ"()
+// CHECK: }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/dllimport-missing-key.cpp b/src/llvm-project/clang/test/CodeGenCXX/dllimport-missing-key.cpp
new file mode 100644
index 0000000..d8ef7aa
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/dllimport-missing-key.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple i686-windows-gnu -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=GNU %s
+
+class __declspec(dllimport) QObjectData {
+public:
+ virtual ~QObjectData() = 0;
+ void *ptr;
+
+ int method() const;
+};
+
+class LocalClass : public QObjectData {
+};
+
+void call() {
+ (new LocalClass())->method();
+}
+
+// GNU-DAG: @_ZTV11QObjectData = available_externally dllimport
+// GNU-DAG: @_ZTS11QObjectData = linkonce_odr
+// GNU-DAG: @_ZTI11QObjectData = linkonce_odr
diff --git a/src/llvm-project/clang/test/CodeGenCXX/dllimport-rtti.cpp b/src/llvm-project/clang/test/CodeGenCXX/dllimport-rtti.cpp
new file mode 100644
index 0000000..d8e6f8e
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/dllimport-rtti.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -triple i686-windows-msvc -emit-llvm -std=c++1y -fms-extensions -O1 -disable-llvm-passes -o - %s | FileCheck %s --check-prefix=MSVC
+// RUN: %clang_cc1 -triple i686-windows-gnu -emit-llvm -std=c++1y -fms-extensions -O1 -disable-llvm-passes -o - %s | FileCheck %s --check-prefix=GNU
+
+struct __declspec(dllimport) S {
+ virtual void f() {}
+} s;
+// MSVC: [[VF_S:.*]] = private unnamed_addr constant { [2 x i8*] }
+// MSVC-DAG: @"??_SS@@6B@" = unnamed_addr alias i8*, getelementptr inbounds ({ [2 x i8*] }, { [2 x i8*] }* [[VF_S]], i32 0, i32 0, i32 1)
+// MSVC-DAG: @"??_R0?AUS@@@8" = linkonce_odr
+// MSVC-DAG: @"??_R1A@?0A@EA@S@@8" = linkonce_odr
+// MSVC-DAG: @"??_R2S@@8" = linkonce_odr
+// MSVC-DAG: @"??_R3S@@8" = linkonce_odr
+
+// GNU-DAG: @_ZTV1S = available_externally dllimport
+// GNU-DAG: @_ZTI1S = linkonce_odr dso_local
+
+struct U : S {
+} u;
+
+struct __declspec(dllimport) V {
+ virtual void f();
+} v;
+// GNU-DAG: @_ZTV1V = available_externally dllimport
+// GNU-DAG: @_ZTS1V = linkonce_odr dso_local
+// GNU-DAG: @_ZTI1V = linkonce_odr dso_local
+
+struct W {
+ __declspec(dllimport) virtual void f();
+ virtual void g();
+} w;
+// GNU-DAG: @_ZTV1W = linkonce_odr dso_local
+// GNU-DAG: @_ZTS1W = linkonce_odr dso_local
+// GNU-DAG: @_ZTI1W = linkonce_odr dso_local
diff --git a/src/llvm-project/clang/test/CodeGenCXX/dllimport-template-sdm.cpp b/src/llvm-project/clang/test/CodeGenCXX/dllimport-template-sdm.cpp
new file mode 100644
index 0000000..33cbdf6
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/dllimport-template-sdm.cpp
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c++14 -fms-extensions -o - %s | FileCheck %s --check-prefix=IMPORT
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c++14 -fms-extensions -o - %s -DTEST_EXPORT | FileCheck %s --check-prefix=EXPORT
+
+#ifndef TEST_EXPORT
+#define DLLATTR __declspec(dllimport)
+#else
+#define DLLATTR __declspec(dllexport)
+#endif
+
+// PR37232: When a dllimport attribute is propagated from a derived class to a
+// base class that happens to be a template specialization, it is only applied
+// to template *methods*, and not static data members. If a dllexport attribute
+// is propagated, it still applies to static data members.
+
+// IMPORT-DAG: @"?sdm@Exporter@@2HB" = available_externally dllimport constant i32 2, align 4
+// IMPORT-DAG: @"?csdm@?$A@H@@2HB" = linkonce_odr dso_local constant i32 2, comdat, align 4
+// IMPORT-DAG: @"?sdm@?$A@H@@2HA" = linkonce_odr dso_local global i32 1, comdat, align 4
+// IMPORT-DAG: @"?sdm@?$B@H@@2HB" = available_externally dllimport constant i32 2, align 4
+// IMPORT-DAG: @"?sdm@?$C@H@@2HB" = available_externally dllimport constant i32 2, align 4
+
+// EXPORT-DAG: @"?sdm@Exporter@@2HB" = weak_odr dso_local dllexport constant i32 2, comdat, align 4
+// EXPORT-DAG: @"?csdm@?$A@H@@2HB" = weak_odr dso_local dllexport constant i32 2, comdat, align 4
+// EXPORT-DAG: @"?sdm@?$A@H@@2HA" = weak_odr dso_local dllexport global i32 1, comdat, align 4
+// EXPORT-DAG: @"?sdm@?$B@H@@2HB" = weak_odr dso_local dllexport constant i32 2, comdat, align 4
+// EXPORT-DAG: @"?sdm@?$C@H@@2HB" = weak_odr dso_local dllexport constant i32 2, comdat, align 4
+
+
+template <typename T> struct A {
+ static constexpr int csdm = 2;
+ static int sdm;
+};
+template <typename T> int A<T>::sdm = 1;
+
+struct DLLATTR Exporter : A<int> {
+ static constexpr int sdm = 2;
+};
+
+template <typename T> struct DLLATTR B { static constexpr int sdm = 2; };
+
+template <typename T> struct DLLATTR C;
+template <typename T> struct C { static constexpr int sdm = 2; };
+
+void takeRef(const int &_Args) {}
+
+int main() {
+ takeRef(Exporter::sdm);
+ takeRef(A<int>::csdm);
+ takeRef(A<int>::sdm);
+ takeRef(B<int>::sdm);
+ takeRef(C<int>::sdm);
+
+ return 1;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/dllimport.cpp b/src/llvm-project/clang/test/CodeGenCXX/dllimport.cpp
new file mode 100644
index 0000000..e9f0e47
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/dllimport.cpp
@@ -0,0 +1,1021 @@
+// RUN: %clang_cc1 -triple i686-windows-msvc -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -DMSABI -w | FileCheck --check-prefix=MSC --check-prefix=M32 %s
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -DMSABI -w | FileCheck --check-prefix=MSC --check-prefix=M64 %s
+// RUN: %clang_cc1 -triple i686-windows-gnu -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=GNU --check-prefix=G32 %s
+// RUN: %clang_cc1 -triple x86_64-windows-gnu -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=GNU --check-prefix=G64 %s
+// RUN: %clang_cc1 -triple i686-windows-msvc -fno-rtti -fno-threadsafe-statics -fms-extensions -fms-compatibility-version=18.00 -emit-llvm -std=c++1y -O1 -disable-llvm-passes -o - %s -DMSABI -w | FileCheck --check-prefix=MO1 --check-prefix=M18 %s
+// RUN: %clang_cc1 -triple i686-windows-msvc -fno-rtti -fno-threadsafe-statics -fms-extensions -fms-compatibility-version=19.00 -emit-llvm -std=c++1y -O1 -disable-llvm-passes -o - %s -DMSABI -w | FileCheck --check-prefix=MO1 --check-prefix=M19 %s
+// RUN: %clang_cc1 -triple i686-windows-gnu -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O1 -o - %s -w | FileCheck --check-prefix=GO1 %s
+
+// CHECK-NOT doesn't play nice with CHECK-DAG, so use separate run lines.
+// RUN: %clang_cc1 -triple i686-windows-msvc -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -DMSABI -w | FileCheck --check-prefix=MSC2 %s
+// RUN: %clang_cc1 -triple i686-windows-gnu -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=GNU2 %s
+
+// Helper structs to make templates more expressive.
+struct ImplicitInst_Imported {};
+struct ImplicitInst_NotImported {};
+struct ExplicitDecl_Imported {};
+struct ExplicitInst_Imported {};
+struct ExplicitSpec_Imported {};
+struct ExplicitSpec_Def_Imported {};
+struct ExplicitSpec_InlineDef_Imported {};
+struct ExplicitSpec_NotImported {};
+
+#define JOIN2(x, y) x##y
+#define JOIN(x, y) JOIN2(x, y)
+#define UNIQ(name) JOIN(name, __LINE__)
+#define USEVARTYPE(type, var) type UNIQ(use)() { return var; }
+#define USEVAR(var) USEVARTYPE(int, var)
+#define USE(func) void UNIQ(use)() { func(); }
+#define USE1(func) void UNIQ(use)() { func(nullptr); }
+#define USEMEMFUNC(class, func) void (class::*UNIQ(use)())() { return &class::func; }
+#define USESTATICMEMFUNC(class, func) void (*UNIQ(use)())() { return &class::func; }
+#define USECLASS(class) void UNIQ(USE)() { class x; }
+#define USECOPYASSIGN(class) class& (class::*UNIQ(use)())(class&) { return &class::operator=; }
+#define USEMOVEASSIGN(class) class& (class::*UNIQ(use)())(class&&) { return &class::operator=; }
+
+//===----------------------------------------------------------------------===//
+// Globals
+//===----------------------------------------------------------------------===//
+
+// Import declaration.
+// MSC-DAG: @"?ExternGlobalDecl@@3HA" = external dllimport global i32
+// GNU-DAG: @ExternGlobalDecl = external dllimport global i32
+__declspec(dllimport) extern int ExternGlobalDecl;
+USEVAR(ExternGlobalDecl)
+
+// dllimport implies a declaration.
+// MSC-DAG: @"?GlobalDecl@@3HA" = external dllimport global i32
+// GNU-DAG: @GlobalDecl = external dllimport global i32
+__declspec(dllimport) int GlobalDecl;
+USEVAR(GlobalDecl)
+
+// Redeclarations
+// MSC-DAG: @"?GlobalRedecl1@@3HA" = external dllimport global i32
+// GNU-DAG: @GlobalRedecl1 = external dllimport global i32
+__declspec(dllimport) extern int GlobalRedecl1;
+__declspec(dllimport) extern int GlobalRedecl1;
+USEVAR(GlobalRedecl1)
+
+// MSC-DAG: @"?GlobalRedecl2a@@3HA" = external dllimport global i32
+// GNU-DAG: @GlobalRedecl2a = external dllimport global i32
+__declspec(dllimport) int GlobalRedecl2a;
+__declspec(dllimport) int GlobalRedecl2a;
+USEVAR(GlobalRedecl2a)
+
+// M32-DAG: @"?GlobalRedecl2b@@3PAHA" = external dllimport global i32*
+// M64-DAG: @"?GlobalRedecl2b@@3PEAHEA" = external dllimport global i32*
+// GNU-DAG: @GlobalRedecl2b = external dllimport global i32*
+int *__attribute__((dllimport)) GlobalRedecl2b;
+int *__attribute__((dllimport)) GlobalRedecl2b;
+USEVARTYPE(int*, GlobalRedecl2b)
+
+// MSC-DAG: @"?GlobalRedecl2c@@3HA" = external dllimport global i32
+// GNU-DAG: @GlobalRedecl2c = external dllimport global i32
+int GlobalRedecl2c __attribute__((dllimport));
+int GlobalRedecl2c __attribute__((dllimport));
+USEVAR(GlobalRedecl2c)
+
+// NB: MSC issues a warning and makes GlobalRedecl3 dllexport. We follow GCC
+// and drop the dllimport with a warning.
+// MSC-DAG: @"?GlobalRedecl3@@3HA" = external dso_local global i32
+// GNU-DAG: @GlobalRedecl3 = external global i32
+__declspec(dllimport) extern int GlobalRedecl3;
+ extern int GlobalRedecl3; // dllimport ignored
+USEVAR(GlobalRedecl3)
+
+// MSC-DAG: @"?ExternalGlobal@ns@@3HA" = external dllimport global i32
+// GNU-DAG: @_ZN2ns14ExternalGlobalE = external dllimport global i32
+namespace ns { __declspec(dllimport) int ExternalGlobal; }
+USEVAR(ns::ExternalGlobal)
+
+int __declspec(dllimport) f();
+// MO1-DAG: @"?x@?1??inlineStaticLocalsFunc@@YAHXZ@4HA" = available_externally dllimport global i32 0
+// MO1-DAG: @"??_B?1??inlineStaticLocalsFunc@@YAHXZ@51" = available_externally dllimport global i32 0
+inline int __declspec(dllimport) inlineStaticLocalsFunc() {
+ static int x = f();
+ return x++;
+};
+USE(inlineStaticLocalsFunc);
+
+// The address of a dllimport global cannot be used in constant initialization.
+// M32-DAG: @"?arr@?1??initializationFunc@@YAPAHXZ@4QBQAHB" = internal global [1 x i32*] zeroinitializer
+// GNU-DAG: @_ZZ18initializationFuncvE3arr = internal global [1 x i32*] zeroinitializer
+int *initializationFunc() {
+ static int *const arr[] = {&ExternGlobalDecl};
+ return arr[0];
+}
+USE(initializationFunc);
+
+
+//===----------------------------------------------------------------------===//
+// Variable templates
+//===----------------------------------------------------------------------===//
+
+// Import declaration.
+// MSC-DAG: @"??$ExternVarTmplDecl@UImplicitInst_Imported@@@@3HA" = external dllimport global i32
+// GNU-DAG: @_Z17ExternVarTmplDeclI21ImplicitInst_ImportedE = external dllimport global i32
+template<typename T> __declspec(dllimport) extern int ExternVarTmplDecl;
+USEVAR(ExternVarTmplDecl<ImplicitInst_Imported>)
+
+// dllimport implies a declaration.
+// MSC-DAG: @"??$VarTmplDecl@UImplicitInst_Imported@@@@3HA" = external dllimport global i32
+// GNU-DAG: @_Z11VarTmplDeclI21ImplicitInst_ImportedE = external dllimport global i32
+template<typename T> __declspec(dllimport) int VarTmplDecl;
+USEVAR(VarTmplDecl<ImplicitInst_Imported>)
+
+// Redeclarations
+// MSC-DAG: @"??$VarTmplRedecl1@UImplicitInst_Imported@@@@3HA" = external dllimport global i32
+// GNU-DAG: @_Z14VarTmplRedecl1I21ImplicitInst_ImportedE = external dllimport global i32
+template<typename T> __declspec(dllimport) extern int VarTmplRedecl1;
+template<typename T> __declspec(dllimport) extern int VarTmplRedecl1;
+USEVAR(VarTmplRedecl1<ImplicitInst_Imported>)
+
+// MSC-DAG: @"??$VarTmplRedecl2@UImplicitInst_Imported@@@@3HA" = external dllimport global i32
+// GNU-DAG: @_Z14VarTmplRedecl2I21ImplicitInst_ImportedE = external dllimport global i32
+template<typename T> __declspec(dllimport) int VarTmplRedecl2;
+template<typename T> __declspec(dllimport) int VarTmplRedecl2;
+USEVAR(VarTmplRedecl2<ImplicitInst_Imported>)
+
+// MSC-DAG: @"??$VarTmplRedecl3@UImplicitInst_Imported@@@@3HA" = external dso_local global i32
+// GNU-DAG: @_Z14VarTmplRedecl3I21ImplicitInst_ImportedE = external global i32
+template<typename T> __declspec(dllimport) extern int VarTmplRedecl3;
+template<typename T> extern int VarTmplRedecl3; // dllimport ignored
+USEVAR(VarTmplRedecl3<ImplicitInst_Imported>)
+
+
+// MSC-DAG: @"??$ExternalVarTmpl@UImplicitInst_Imported@@@ns@@3HA" = external dllimport global i32
+// GNU-DAG: @_ZN2ns15ExternalVarTmplI21ImplicitInst_ImportedEE = external dllimport global i32
+namespace ns { template<typename T> __declspec(dllimport) int ExternalVarTmpl; }
+USEVAR(ns::ExternalVarTmpl<ImplicitInst_Imported>)
+
+
+template<typename T> int VarTmpl;
+template<typename T> __declspec(dllimport) int ImportedVarTmpl;
+
+// Import implicit instantiation of an imported variable template.
+// MSC-DAG: @"??$ImportedVarTmpl@UImplicitInst_Imported@@@@3HA" = external dllimport global i32
+// GNU-DAG: @_Z15ImportedVarTmplI21ImplicitInst_ImportedE = external dllimport global i32
+USEVAR(ImportedVarTmpl<ImplicitInst_Imported>)
+
+// Import explicit instantiation declaration of an imported variable template.
+// MSC-DAG: @"??$ImportedVarTmpl@UExplicitDecl_Imported@@@@3HA" = external dllimport global i32
+// GNU-DAG: @_Z15ImportedVarTmplI21ExplicitDecl_ImportedE = external dllimport global i32
+extern template int ImportedVarTmpl<ExplicitDecl_Imported>;
+USEVAR(ImportedVarTmpl<ExplicitDecl_Imported>)
+
+// An explicit instantiation definition of an imported variable template cannot
+// be imported because the template must be defined which is illegal.
+
+// Import specialization of an imported variable template.
+// MSC-DAG: @"??$ImportedVarTmpl@UExplicitSpec_Imported@@@@3HA" = external dllimport global i32
+// GNU-DAG: @_Z15ImportedVarTmplI21ExplicitSpec_ImportedE = external dllimport global i32
+template<> __declspec(dllimport) int ImportedVarTmpl<ExplicitSpec_Imported>;
+USEVAR(ImportedVarTmpl<ExplicitSpec_Imported>)
+
+// Not importing specialization of an imported variable template without
+// explicit dllimport.
+// MSC-DAG: @"??$ImportedVarTmpl@UExplicitSpec_NotImported@@@@3HA" = dso_local global i32 0, align 4
+// GNU-DAG: @_Z15ImportedVarTmplI24ExplicitSpec_NotImportedE = dso_local global i32 0, align 4
+template<> int ImportedVarTmpl<ExplicitSpec_NotImported>;
+USEVAR(ImportedVarTmpl<ExplicitSpec_NotImported>)
+
+// Import explicit instantiation declaration of a non-imported variable template.
+// MSC-DAG: @"??$VarTmpl@UExplicitDecl_Imported@@@@3HA" = external dllimport global i32
+// GNU-DAG: @_Z7VarTmplI21ExplicitDecl_ImportedE = external dllimport global i32
+extern template __declspec(dllimport) int VarTmpl<ExplicitDecl_Imported>;
+USEVAR(VarTmpl<ExplicitDecl_Imported>)
+
+// Import explicit instantiation definition of a non-imported variable template.
+// MSC-DAG: @"??$VarTmpl@UExplicitInst_Imported@@@@3HA" = external dllimport global i32
+// GNU-DAG: @_Z7VarTmplI21ExplicitInst_ImportedE = external dllimport global i32
+template __declspec(dllimport) int VarTmpl<ExplicitInst_Imported>;
+USEVAR(VarTmpl<ExplicitInst_Imported>)
+
+// Import specialization of a non-imported variable template.
+// MSC-DAG: @"??$VarTmpl@UExplicitSpec_Imported@@@@3HA" = external dllimport global i32
+// GNU-DAG: @_Z7VarTmplI21ExplicitSpec_ImportedE = external dllimport global i32
+template<> __declspec(dllimport) int VarTmpl<ExplicitSpec_Imported>;
+USEVAR(VarTmpl<ExplicitSpec_Imported>)
+
+
+
+//===----------------------------------------------------------------------===//
+// Functions
+//===----------------------------------------------------------------------===//
+
+// GNU-DAG: declare dso_local void @_ZdlPv(i8*)
+
+// Import function declaration.
+// MSC-DAG: declare dllimport void @"?decl@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z4declv()
+__declspec(dllimport) void decl();
+USE(decl)
+
+// extern "C"
+// MSC-DAG: declare dllimport void @externC()
+// GNU-DAG: declare dllimport void @externC()
+extern "C" __declspec(dllimport) void externC();
+USE(externC)
+
+// Import inline function.
+// MSC-DAG: declare dllimport void @"?inlineFunc@@YAXXZ"()
+// GNU-DAG: define linkonce_odr dso_local void @_Z10inlineFuncv()
+// MO1-DAG: define available_externally dllimport void @"?inlineFunc@@YAXXZ"()
+// GO1-DAG: define linkonce_odr dso_local void @_Z10inlineFuncv()
+__declspec(dllimport) inline void inlineFunc() {}
+USE(inlineFunc)
+
+// MSC-DAG: declare dllimport void @"?inlineDecl@@YAXXZ"()
+// GNU-DAG: define linkonce_odr dso_local void @_Z10inlineDeclv()
+// MO1-DAG: define available_externally dllimport void @"?inlineDecl@@YAXXZ"()
+// GO1-DAG: define linkonce_odr dso_local void @_Z10inlineDeclv()
+__declspec(dllimport) inline void inlineDecl();
+ void inlineDecl() {}
+USE(inlineDecl)
+
+// MSC-DAG: declare dllimport void @"?inlineDef@@YAXXZ"()
+// GNU-DAG: define linkonce_odr dso_local void @_Z9inlineDefv()
+// MO1-DAG: define available_externally dllimport void @"?inlineDef@@YAXXZ"()
+// GO1-DAG: define linkonce_odr dso_local void @_Z9inlineDefv()
+__declspec(dllimport) void inlineDef();
+ inline void inlineDef() {}
+USE(inlineDef)
+
+// inline attributes
+// MSC-DAG: declare dllimport void @"?noinline@@YAXXZ"()
+// GNU-DAG: define linkonce_odr dso_local void @_Z8noinlinev()
+__declspec(dllimport) __attribute__((noinline)) inline void noinline() {}
+USE(noinline)
+
+// MSC2-NOT: @"?alwaysInline@@YAXXZ"()
+// GNU2-NOT: @_Z12alwaysInlinev()
+__declspec(dllimport) __attribute__((always_inline)) inline void alwaysInline() {}
+USE(alwaysInline)
+
+// Redeclarations
+// MSC-DAG: declare dllimport void @"?redecl1@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z7redecl1v()
+__declspec(dllimport) void redecl1();
+__declspec(dllimport) void redecl1();
+USE(redecl1)
+
+// NB: MSC issues a warning and makes redecl2/redecl3 dllexport. We follow GCC
+// and drop the dllimport with a warning.
+// MSC-DAG: declare dso_local void @"?redecl2@@YAXXZ"()
+// GNU-DAG: declare dso_local void @_Z7redecl2v()
+__declspec(dllimport) void redecl2();
+ void redecl2();
+USE(redecl2)
+
+// MSC-DAG: define dso_local dllexport void @"?redecl3@@YAXXZ"()
+// GNU-DAG: define dso_local void @_Z7redecl3v()
+__declspec(dllimport) void redecl3();
+ void redecl3() {} // dllimport ignored
+USE(redecl3)
+
+
+// Friend functions
+// MSC-DAG: declare dllimport void @"?friend1@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z7friend1v()
+// MSC-DAG: declare dso_local void @"?friend2@@YAXXZ"()
+// GNU-DAG: declare dso_local void @_Z7friend2v()
+// MSC-DAG: define dso_local dllexport void @"?friend3@@YAXXZ"()
+// GNU-DAG: define dso_local void @_Z7friend3v()
+// MSC-DAG: declare dso_local void @"?friend4@@YAXXZ"()
+// GNU-DAG: declare dso_local void @_Z7friend4v()
+// MSC-DAG: declare dllimport void @"?friend5@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z7friend5v()
+
+struct FuncFriend {
+ friend __declspec(dllimport) void friend1();
+ friend __declspec(dllimport) void friend2();
+ friend __declspec(dllimport) void friend3();
+};
+__declspec(dllimport) void friend1();
+ void friend2(); // dllimport ignored
+ void friend3() {} // dllimport ignored
+
+__declspec(dllimport) void friend4();
+__declspec(dllimport) void friend5();
+struct FuncFriendRedecl {
+ friend void friend4(); // dllimport ignored
+ friend void ::friend5();
+};
+USE(friend1)
+USE(friend2)
+USE(friend3)
+USE(friend4)
+USE(friend5)
+
+// Implicit declarations can be redeclared with dllimport.
+// MSC-DAG: declare dllimport noalias i8* @"??2@{{YAPAXI|YAPEAX_K}}@Z"(
+// GNU-DAG: declare dllimport noalias i8* @_Znw{{[yj]}}(
+__declspec(dllimport) void* operator new(__SIZE_TYPE__ n);
+void UNIQ(use)() { ::operator new(42); }
+
+// MSC-DAG: declare dllimport void @"?externalFunc@ns@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_ZN2ns12externalFuncEv()
+namespace ns { __declspec(dllimport) void externalFunc(); }
+USE(ns::externalFunc)
+
+// A dllimport function referencing non-imported vars or functions must not be available_externally.
+
+__declspec(dllimport) int ImportedVar;
+int NonImportedVar;
+__declspec(dllimport) int ImportedFunc();
+int NonImportedFunc();
+struct ClassWithNonImportedMethod { int f(); };
+
+__declspec(dllimport) inline int ReferencingImportedVar() { return ImportedVar; }
+// MO1-DAG: define available_externally dllimport i32 @"?ReferencingImportedVar@@YAHXZ"
+__declspec(dllimport) inline int ReferencingNonImportedVar() { return NonImportedVar; }
+// MO1-DAG: declare dllimport i32 @"?ReferencingNonImportedVar@@YAHXZ"()
+__declspec(dllimport) inline int ReferencingImportedFunc() { return ImportedFunc(); }
+// MO1-DAG: define available_externally dllimport i32 @"?ReferencingImportedFunc@@YAHXZ"
+__declspec(dllimport) inline int ReferencingNonImportedFunc() { return NonImportedFunc(); }
+// MO1-DAG: declare dllimport i32 @"?ReferencingNonImportedFunc@@YAHXZ"()
+__declspec(dllimport) inline int ReferencingNonImportedMethod(ClassWithNonImportedMethod *x) { return x->f(); }
+// MO1-DAG: declare dllimport i32 @"?ReferencingNonImportedMethod
+__declspec(dllimport) inline int ReferencingClassMemberPtr(int (ClassWithNonImportedMethod::*p)(), ClassWithNonImportedMethod *x) { return (x->*p)(); }
+// MO1-DAG: define available_externally dllimport i32 @"?ReferencingClassMemberPtr@@YAHP8ClassWithNonImportedMethod@@AEHXZPAU1@@Z"
+USE(ReferencingImportedVar)
+USE(ReferencingNonImportedVar)
+USE(ReferencingImportedFunc)
+USE(ReferencingNonImportedFunc)
+USE1(ReferencingNonImportedMethod)
+void UNIQ(use)() { ReferencingClassMemberPtr(&ClassWithNonImportedMethod::f, nullptr); }
+// References to operator new and delete count too, despite not being DeclRefExprs.
+__declspec(dllimport) inline int *ReferencingNonImportedNew() { return new int[2]; }
+// MO1-DAG: declare dllimport i32* @"?ReferencingNonImportedNew@@YAPAHXZ"
+__declspec(dllimport) inline int *ReferencingNonImportedDelete() { delete (int*)nullptr; }
+// MO1-DAG: declare dllimport i32* @"?ReferencingNonImportedDelete@@YAPAHXZ"
+USE(ReferencingNonImportedNew)
+USE(ReferencingNonImportedDelete)
+__declspec(dllimport) void* operator new[](__SIZE_TYPE__);
+__declspec(dllimport) void operator delete(void*);
+__declspec(dllimport) inline int *ReferencingImportedNew() { return new int[2]; }
+// MO1-DAG: define available_externally dllimport i32* @"?ReferencingImportedNew@@YAPAHXZ"
+__declspec(dllimport) inline int *ReferencingImportedDelete() { delete (int*)nullptr; }
+// MO1-DAG: define available_externally dllimport i32* @"?ReferencingImportedDelete@@YAPAHXZ"
+USE(ReferencingImportedNew)
+USE(ReferencingImportedDelete)
+struct ClassWithDtor { ~ClassWithDtor() {} };
+struct __declspec(dllimport) ClassWithNonDllImportField { using X = ClassWithDtor; X t[2]; };
+struct __declspec(dllimport) ClassWithNonDllImportBase : public ClassWithDtor { };
+USECLASS(ClassWithNonDllImportField);
+USECLASS(ClassWithNonDllImportBase);
+// MO1-DAG: declare dllimport x86_thiscallcc void @"??1ClassWithNonDllImportBase@@QAE@XZ"(%struct.ClassWithNonDllImportBase*)
+// MO1-DAG: declare dllimport x86_thiscallcc void @"??1ClassWithNonDllImportField@@QAE@XZ"(%struct.ClassWithNonDllImportField*)
+struct ClassWithCtor { ClassWithCtor() {} };
+struct __declspec(dllimport) ClassWithNonDllImportFieldWithCtor { ClassWithCtor t; };
+USECLASS(ClassWithNonDllImportFieldWithCtor);
+// MO1-DAG: declare dllimport x86_thiscallcc %struct.ClassWithNonDllImportFieldWithCtor* @"??0ClassWithNonDllImportFieldWithCtor@@QAE@XZ"(%struct.ClassWithNonDllImportFieldWithCtor* returned)
+struct ClassWithImplicitDtor { __declspec(dllimport) ClassWithImplicitDtor(); ClassWithDtor member; };
+__declspec(dllimport) inline void ReferencingDtorThroughDefinition() { ClassWithImplicitDtor x; };
+USE(ReferencingDtorThroughDefinition)
+// MO1-DAG: declare dllimport void @"?ReferencingDtorThroughDefinition@@YAXXZ"()
+__declspec(dllimport) inline void ReferencingDtorThroughTemporary() { ClassWithImplicitDtor(); };
+USE(ReferencingDtorThroughTemporary)
+// MO1-DAG: declare dllimport void @"?ReferencingDtorThroughTemporary@@YAXXZ"()
+
+// A dllimport function with a TLS variable must not be available_externally.
+__declspec(dllimport) inline void FunctionWithTLSVar() { static __thread int x = 42; }
+// MO1-DAG: declare dllimport void @"?FunctionWithTLSVar@@YAXXZ"
+__declspec(dllimport) inline void FunctionWithNormalVar() { static int x = 42; }
+// MO1-DAG: define available_externally dllimport void @"?FunctionWithNormalVar@@YAXXZ"
+USE(FunctionWithTLSVar)
+USE(FunctionWithNormalVar)
+
+
+//===----------------------------------------------------------------------===//
+// Function templates
+//===----------------------------------------------------------------------===//
+
+// Import function template declaration.
+// MSC-DAG: declare dllimport void @"??$funcTmplDecl@UImplicitInst_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z12funcTmplDeclI21ImplicitInst_ImportedEvv()
+template<typename T> __declspec(dllimport) void funcTmplDecl();
+USE(funcTmplDecl<ImplicitInst_Imported>)
+
+// Function template definitions cannot be imported.
+
+// Import inline function template.
+// MSC-DAG: declare dllimport void @"??$inlineFuncTmpl1@UImplicitInst_Imported@@@@YAXXZ"()
+// GNU-DAG: define linkonce_odr dso_local void @_Z15inlineFuncTmpl1I21ImplicitInst_ImportedEvv()
+// MO1-DAG: define available_externally dllimport void @"??$inlineFuncTmpl1@UImplicitInst_Imported@@@@YAXXZ"()
+// GO1-DAG: define linkonce_odr dso_local void @_Z15inlineFuncTmpl1I21ImplicitInst_ImportedEvv()
+template<typename T> __declspec(dllimport) inline void inlineFuncTmpl1() {}
+USE(inlineFuncTmpl1<ImplicitInst_Imported>)
+
+// MSC-DAG: declare dllimport void @"??$inlineFuncTmpl2@UImplicitInst_Imported@@@@YAXXZ"()
+// GNU-DAG: define linkonce_odr dso_local void @_Z15inlineFuncTmpl2I21ImplicitInst_ImportedEvv()
+// MO1-DAG: define available_externally dllimport void @"??$inlineFuncTmpl2@UImplicitInst_Imported@@@@YAXXZ"()
+// GO1-DAG: define linkonce_odr dso_local void @_Z15inlineFuncTmpl2I21ImplicitInst_ImportedEvv()
+template<typename T> inline void __attribute__((dllimport)) inlineFuncTmpl2() {}
+USE(inlineFuncTmpl2<ImplicitInst_Imported>)
+
+// MSC-DAG: define linkonce_odr dso_local void @"??$inlineFuncTmplDecl@UImplicitInst_Imported@@@@YAXXZ"()
+// GNU-DAG: define linkonce_odr dso_local void @_Z18inlineFuncTmplDeclI21ImplicitInst_ImportedEvv()
+// MO1-DAG: define linkonce_odr dso_local void @"??$inlineFuncTmplDecl@UImplicitInst_Imported@@@@YAXXZ"()
+// GO1-DAG: define linkonce_odr dso_local void @_Z18inlineFuncTmplDeclI21ImplicitInst_ImportedEvv()
+template<typename T> __declspec(dllimport) inline void inlineFuncTmplDecl();
+template<typename T> void inlineFuncTmplDecl() {}
+USE(inlineFuncTmplDecl<ImplicitInst_Imported>)
+
+// MSC-DAG: define linkonce_odr dso_local void @"??$inlineFuncTmplDef@UImplicitInst_Imported@@@@YAXXZ"()
+// GNU-DAG: define linkonce_odr dso_local void @_Z17inlineFuncTmplDefI21ImplicitInst_ImportedEvv()
+// MO1-DAG: define linkonce_odr dso_local void @"??$inlineFuncTmplDef@UImplicitInst_Imported@@@@YAXXZ"()
+// GO1-DAG: define linkonce_odr dso_local void @_Z17inlineFuncTmplDefI21ImplicitInst_ImportedEvv()
+template<typename T> __declspec(dllimport) void inlineFuncTmplDef();
+template<typename T> inline void inlineFuncTmplDef() {}
+USE(inlineFuncTmplDef<ImplicitInst_Imported>)
+
+
+// Redeclarations
+// MSC-DAG: declare dllimport void @"??$funcTmplRedecl1@UImplicitInst_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z15funcTmplRedecl1I21ImplicitInst_ImportedEvv()
+template<typename T> __declspec(dllimport) void funcTmplRedecl1();
+template<typename T> __declspec(dllimport) void funcTmplRedecl1();
+USE(funcTmplRedecl1<ImplicitInst_Imported>)
+
+// MSC-DAG: declare dso_local void @"??$funcTmplRedecl2@UImplicitInst_NotImported@@@@YAXXZ"()
+// GNU-DAG: declare dso_local void @_Z15funcTmplRedecl2I24ImplicitInst_NotImportedEvv()
+template<typename T> __declspec(dllimport) void funcTmplRedecl2();
+template<typename T> void funcTmplRedecl2(); // dllimport ignored
+USE(funcTmplRedecl2<ImplicitInst_NotImported>)
+
+// MSC-DAG: define linkonce_odr dso_local void @"??$funcTmplRedecl3@UImplicitInst_NotImported@@@@YAXXZ"()
+// GNU-DAG: define linkonce_odr dso_local void @_Z15funcTmplRedecl3I24ImplicitInst_NotImportedEvv()
+template<typename T> __declspec(dllimport) void funcTmplRedecl3();
+template<typename T> void funcTmplRedecl3() {} // dllimport ignored
+USE(funcTmplRedecl3<ImplicitInst_NotImported>)
+
+
+// Function template friends
+// MSC-DAG: declare dllimport void @"??$funcTmplFriend1@UImplicitInst_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z15funcTmplFriend1I21ImplicitInst_ImportedEvv()
+// MSC-DAG: declare dso_local void @"??$funcTmplFriend2@UImplicitInst_NotImported@@@@YAXXZ"()
+// GNU-DAG: declare dso_local void @_Z15funcTmplFriend2I24ImplicitInst_NotImportedEvv()
+// MSC-DAG: define linkonce_odr dso_local void @"??$funcTmplFriend3@UImplicitInst_NotImported@@@@YAXXZ"()
+// GNU-DAG: define linkonce_odr dso_local void @_Z15funcTmplFriend3I24ImplicitInst_NotImportedEvv()
+// MSC-DAG: define linkonce_odr dso_local void @"??$funcTmplFriend4@UImplicitInst_Imported@@@@YAXXZ"()
+// GNU-DAG: define linkonce_odr dso_local void @_Z15funcTmplFriend4I21ImplicitInst_ImportedEvv()
+struct FuncTmplFriend {
+ template<typename T> friend __declspec(dllimport) void funcTmplFriend1();
+ template<typename T> friend __declspec(dllimport) void funcTmplFriend2();
+ template<typename T> friend __declspec(dllimport) void funcTmplFriend3();
+ template<typename T> friend __declspec(dllimport) inline void funcTmplFriend4();
+};
+template<typename T> __declspec(dllimport) void funcTmplFriend1();
+template<typename T> void funcTmplFriend2(); // dllimport ignored
+template<typename T> void funcTmplFriend3() {} // dllimport ignored
+template<typename T> inline void funcTmplFriend4() {}
+USE(funcTmplFriend1<ImplicitInst_Imported>)
+USE(funcTmplFriend2<ImplicitInst_NotImported>)
+USE(funcTmplFriend3<ImplicitInst_NotImported>)
+USE(funcTmplFriend4<ImplicitInst_Imported>)
+
+// MSC-DAG: declare dllimport void @"??$externalFuncTmpl@UImplicitInst_Imported@@@ns@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_ZN2ns16externalFuncTmplI21ImplicitInst_ImportedEEvv()
+namespace ns { template<typename T> __declspec(dllimport) void externalFuncTmpl(); }
+USE(ns::externalFuncTmpl<ImplicitInst_Imported>)
+
+
+template<typename T> void funcTmpl() {}
+template<typename T> inline void inlineFuncTmpl() {}
+template<typename T> __declspec(dllimport) void importedFuncTmplDecl();
+template<typename T> __declspec(dllimport) inline void importedFuncTmpl() {}
+
+// Import implicit instantiation of an imported function template.
+// MSC-DAG: declare dllimport void @"??$importedFuncTmplDecl@UImplicitInst_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z20importedFuncTmplDeclI21ImplicitInst_ImportedEvv()
+USE(importedFuncTmplDecl<ImplicitInst_Imported>)
+
+// MSC-DAG: declare dllimport void @"??$importedFuncTmpl@UImplicitInst_Imported@@@@YAXXZ"()
+// GNU-DAG: define linkonce_odr dso_local void @_Z16importedFuncTmplI21ImplicitInst_ImportedEvv()
+// MO1-DAG: define available_externally dllimport void @"??$importedFuncTmpl@UImplicitInst_Imported@@@@YAXXZ"()
+// GO1-DAG: define linkonce_odr dso_local void @_Z16importedFuncTmplI21ImplicitInst_ImportedEvv()
+USE(importedFuncTmpl<ImplicitInst_Imported>)
+
+// Import explicit instantiation declaration of an imported function template.
+// MSC-DAG: declare dllimport void @"??$importedFuncTmpl@UExplicitDecl_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dso_local void @_Z16importedFuncTmplI21ExplicitDecl_ImportedEvv()
+// MO1-DAG: define available_externally dllimport void @"??$importedFuncTmpl@UExplicitDecl_Imported@@@@YAXXZ"()
+// GO1-DAG: define available_externally dso_local void @_Z16importedFuncTmplI21ExplicitDecl_ImportedEvv()
+extern template void importedFuncTmpl<ExplicitDecl_Imported>();
+USE(importedFuncTmpl<ExplicitDecl_Imported>)
+
+// Import explicit instantiation definition of an imported function template.
+// MSC-DAG: declare dllimport void @"??$importedFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dso_local void @_Z16importedFuncTmplI21ExplicitInst_ImportedEvv()
+// MO1-DAG: define available_externally dllimport void @"??$importedFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"()
+// GO1-DAG: define weak_odr dso_local void @_Z16importedFuncTmplI21ExplicitInst_ImportedEvv()
+template void importedFuncTmpl<ExplicitInst_Imported>();
+USE(importedFuncTmpl<ExplicitInst_Imported>)
+
+
+// Import specialization of an imported function template.
+// MSC-DAG: declare dllimport void @"??$importedFuncTmplDecl@UExplicitSpec_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z20importedFuncTmplDeclI21ExplicitSpec_ImportedEvv()
+template<> __declspec(dllimport) void importedFuncTmplDecl<ExplicitSpec_Imported>();
+USE(importedFuncTmplDecl<ExplicitSpec_Imported>)
+
+// MSC-DAG-FIXME: declare dllimport void @"??$importedFuncTmplDecl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
+// MO1-DAG-FIXME: define available_externally dllimport void @"??$importedFuncTmplDecl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
+#ifdef MSABI
+//template<> __declspec(dllimport) void importedFuncTmplDecl<ExplicitSpec_Def_Imported>() {}
+//USE(importedFuncTmplDecl<ExplicitSpec_Def_Imported>)
+#endif
+
+// MSC-DAG: declare dllimport void @"??$importedFuncTmplDecl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
+// GNU-DAG: define linkonce_odr dso_local void @_Z20importedFuncTmplDeclI31ExplicitSpec_InlineDef_ImportedEvv()
+// MO1-DAG: define available_externally dllimport void @"??$importedFuncTmplDecl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
+// GO1-DAG: define linkonce_odr dso_local void @_Z20importedFuncTmplDeclI31ExplicitSpec_InlineDef_ImportedEvv()
+template<> __declspec(dllimport) inline void importedFuncTmplDecl<ExplicitSpec_InlineDef_Imported>() {}
+USE(importedFuncTmplDecl<ExplicitSpec_InlineDef_Imported>)
+
+
+// MSC-DAG: declare dllimport void @"??$importedFuncTmpl@UExplicitSpec_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z16importedFuncTmplI21ExplicitSpec_ImportedEvv()
+template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Imported>();
+USE(importedFuncTmpl<ExplicitSpec_Imported>)
+
+// MSC-DAG-FIXME: declare dllimport void @"??$importedFuncTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
+// MO1-DAG-FIXME: define available_externally dllimport void @"??$importedFuncTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
+#ifdef MSABI
+//template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Def_Imported>() {}
+//USE(importedFuncTmpl<ExplicitSpec_Def_Imported>)
+#endif
+
+// MSC-DAG: declare dllimport void @"??$importedFuncTmpl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
+// GNU-DAG: define linkonce_odr dso_local void @_Z16importedFuncTmplI31ExplicitSpec_InlineDef_ImportedEvv()
+// MO1-DAG: define available_externally dllimport void @"??$importedFuncTmpl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
+// GO1-DAG: define linkonce_odr dso_local void @_Z16importedFuncTmplI31ExplicitSpec_InlineDef_ImportedEvv()
+template<> __declspec(dllimport) inline void importedFuncTmpl<ExplicitSpec_InlineDef_Imported>() {}
+USE(importedFuncTmpl<ExplicitSpec_InlineDef_Imported>)
+
+
+// Not importing specialization of an imported function template without
+// explicit dllimport.
+// MSC-DAG: define dso_local void @"??$importedFuncTmpl@UExplicitSpec_NotImported@@@@YAXXZ"()
+// GNU-DAG: define dso_local void @_Z16importedFuncTmplI24ExplicitSpec_NotImportedEvv()
+template<> void importedFuncTmpl<ExplicitSpec_NotImported>() {}
+USE(importedFuncTmpl<ExplicitSpec_NotImported>)
+
+
+// Import explicit instantiation declaration of a non-imported function template.
+// MSC-DAG: declare dllimport void @"??$funcTmpl@UExplicitDecl_Imported@@@@YAXXZ"()
+// MSC-DAG: declare dllimport void @"??$inlineFuncTmpl@UExplicitDecl_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z8funcTmplI21ExplicitDecl_ImportedEvv()
+// GNU-DAG: declare dso_local void @_Z14inlineFuncTmplI21ExplicitDecl_ImportedEvv()
+// MO1-DAG: define available_externally dllimport void @"??$inlineFuncTmpl@UExplicitDecl_Imported@@@@YAXXZ"()
+// GO1-DAG: define available_externally dso_local void @_Z14inlineFuncTmplI21ExplicitDecl_ImportedEvv()
+extern template __declspec(dllimport) void funcTmpl<ExplicitDecl_Imported>();
+extern template __declspec(dllimport) void inlineFuncTmpl<ExplicitDecl_Imported>();
+USE(funcTmpl<ExplicitDecl_Imported>)
+USE(inlineFuncTmpl<ExplicitDecl_Imported>)
+
+
+// Import explicit instantiation definition of a non-imported function template.
+// MSC-DAG: declare dllimport void @"??$funcTmpl@UExplicitInst_Imported@@@@YAXXZ"()
+// MSC-DAG: declare dllimport void @"??$inlineFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z8funcTmplI21ExplicitInst_ImportedEvv()
+// GNU-DAG: define weak_odr dso_local void @_Z14inlineFuncTmplI21ExplicitInst_ImportedEvv()
+// MO1-DAG: declare dllimport void @"??$funcTmpl@UExplicitInst_Imported@@@@YAXXZ"()
+// MO1-DAG: define available_externally dllimport void @"??$inlineFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"()
+// GO1-DAG: define available_externally dllimport void @_Z8funcTmplI21ExplicitInst_ImportedEvv()
+// GO1-DAG: define weak_odr dso_local void @_Z14inlineFuncTmplI21ExplicitInst_ImportedEvv()
+template __declspec(dllimport) void funcTmpl<ExplicitInst_Imported>();
+template __declspec(dllimport) void inlineFuncTmpl<ExplicitInst_Imported>();
+USE(funcTmpl<ExplicitInst_Imported>)
+USE(inlineFuncTmpl<ExplicitInst_Imported>)
+
+
+// Import specialization of a non-imported function template.
+// MSC-DAG: declare dllimport void @"??$funcTmpl@UExplicitSpec_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z8funcTmplI21ExplicitSpec_ImportedEvv()
+template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Imported>();
+USE(funcTmpl<ExplicitSpec_Imported>)
+
+// MSC-DAG-FIXME: declare dllimport void @"??$funcTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
+// MO1-DAG-FIXME: define available_externally dllimport void @"??$funcTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
+#ifdef MSABI
+//template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Def_Imported>() {}
+//USE(funcTmpl<ExplicitSpec_Def_Imported>)
+#endif
+
+// MSC-DAG: declare dllimport void @"??$funcTmpl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
+// GNU-DAG: define linkonce_odr dso_local void @_Z8funcTmplI31ExplicitSpec_InlineDef_ImportedEvv()
+// MO1-DAG: define available_externally dllimport void @"??$funcTmpl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
+// GO1-DAG: define linkonce_odr dso_local void @_Z8funcTmplI31ExplicitSpec_InlineDef_ImportedEvv()
+template<> __declspec(dllimport) inline void funcTmpl<ExplicitSpec_InlineDef_Imported>() {}
+USE(funcTmpl<ExplicitSpec_InlineDef_Imported>)
+
+#ifdef MSABI
+namespace pr35435 {
+struct X;
+template <typename T> struct __declspec(dllimport) S {
+ void foo(T *t) { t->problem(); }
+};
+template void S<X>::foo(X*); // Cannot be instantiated because X is incomplete; dllimport means it's treated as an instantiation decl.
+}
+#endif
+
+
+//===----------------------------------------------------------------------===//
+// Classes
+//===----------------------------------------------------------------------===//
+
+struct __declspec(dllimport) T {
+ void a() {}
+ // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"?a@T@@QAEXXZ"
+
+ static void StaticMethod();
+ // MSC-DAG: declare dllimport void @"?StaticMethod@T@@SAXXZ"()
+ // GNU-DAG: declare dllimport void @_ZN1T12StaticMethodEv()
+
+ static int b;
+ // MO1-DAG: @"?b@T@@2HA" = external dllimport global i32
+
+ T& operator=(T&) = default;
+ // MO1-DAG: define available_externally dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.T* @"??4T@@QAEAAU0@AAU0@@Z"
+
+ T& operator=(T&&) = default;
+ // Note: Don't mark inline move operators dllimport because current MSVC versions don't export them.
+ // M18-DAG: define linkonce_odr dso_local x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.T* @"??4T@@QAEAAU0@$$QAU0@@Z"
+ // M19-DAG: define available_externally dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.T* @"??4T@@QAEAAU0@$$QAU0@@Z"
+};
+USEMEMFUNC(T, a)
+USESTATICMEMFUNC(T, StaticMethod)
+USEVAR(T::b)
+USECOPYASSIGN(T)
+USEMOVEASSIGN(T)
+
+template <typename T> struct __declspec(dllimport) U { void foo() {} };
+// MO1-DAG: define available_externally dllimport x86_thiscallcc void @"?foo@?$U@H@@QAEXXZ"
+struct __declspec(dllimport) V : public U<int> { };
+USEMEMFUNC(V, foo)
+
+struct __declspec(dllimport) W { virtual void foo() {} };
+USECLASS(W)
+// vftable:
+// MO1-DAG: @"??_SW@@6B@" = linkonce_odr unnamed_addr constant { [1 x i8*] } { [1 x i8*] [i8* bitcast (void (%struct.W*)* @"?foo@W@@UAEXXZ" to i8*)] }
+// GO1-DAG: @_ZTV1W = available_externally dllimport unnamed_addr constant { [3 x i8*] } { [3 x i8*] [i8* null, i8* null, i8* bitcast (void (%struct.W*)* @_ZN1W3fooEv to i8*)] }
+
+struct __declspec(dllimport) KeyFuncClass {
+ constexpr KeyFuncClass() {}
+ virtual void foo();
+};
+extern constexpr KeyFuncClass keyFuncClassVar = {};
+// G32-DAG: @_ZTV12KeyFuncClass = external dllimport unnamed_addr constant { [3 x i8*] }
+
+struct __declspec(dllimport) X : public virtual W {};
+USECLASS(X)
+// vbtable:
+// MO1-DAG: @"??_8X@@7B@" = available_externally dllimport unnamed_addr constant [2 x i32] [i32 0, i32 4]
+
+struct __declspec(dllimport) Y {
+ int x;
+};
+
+struct __declspec(dllimport) Z { virtual ~Z() {} };
+USECLASS(Z)
+// User-defined dtor:
+// MO1-DAG: define available_externally dllimport x86_thiscallcc void @"??1Z@@UAE@XZ"
+
+namespace DontUseDtorAlias {
+ struct __declspec(dllimport) A { ~A(); };
+ struct __declspec(dllimport) B : A { ~B(); };
+ inline A::~A() { }
+ inline B::~B() { }
+ // Emit a real definition of B's constructor; don't alias it to A's.
+ // MO1-DAG: available_externally dllimport x86_thiscallcc void @"??1B@DontUseDtorAlias@@QAE@XZ"
+ USECLASS(B)
+}
+
+namespace Vtordisp {
+ // Don't dllimport the vtordisp.
+ // MO1-DAG: define linkonce_odr dso_local x86_thiscallcc void @"?f@?$C@H@Vtordisp@@$4PPPPPPPM@A@AEXXZ"
+
+ class __declspec(dllimport) Base {
+ virtual void f() {}
+ };
+ template <typename T>
+ class __declspec(dllimport) C : virtual public Base {
+ public:
+ C() {}
+ virtual void f() {}
+ };
+ USECLASS(C<int>);
+}
+
+namespace ClassTemplateStaticDef {
+ // Regular template static field:
+ template <typename T> struct __declspec(dllimport) S {
+ static int x;
+ };
+ template <typename T> int S<T>::x;
+ // MSC-DAG: @"?x@?$S@H@ClassTemplateStaticDef@@2HA" = external dllimport global i32
+ int f() { return S<int>::x; }
+
+ // Partial class template specialization static field:
+ template <typename A> struct T;
+ template <typename A> struct __declspec(dllimport) T<A*> {
+ static int x;
+ };
+ template <typename A> int T<A*>::x;
+ // GNU-DAG: @_ZN22ClassTemplateStaticDef1TIPvE1xE = external dllimport global i32
+ int g() { return T<void*>::x; }
+}
+
+namespace PR19933 {
+// Don't dynamically initialize dllimport vars.
+// MSC2-NOT: @llvm.global_ctors
+// GNU2-NOT: @llvm.global_ctors
+
+ struct NonPOD { NonPOD(); };
+ template <typename T> struct A { static NonPOD x; };
+ template <typename T> NonPOD A<T>::x;
+ template struct __declspec(dllimport) A<int>;
+ USEVARTYPE(NonPOD, A<int>::x);
+ // MSC-DAG: @"?x@?$A@H@PR19933@@2UNonPOD@2@A" = external dllimport global %"struct.PR19933::NonPOD"
+
+ int f();
+ template <typename T> struct B { static int x; };
+ template <typename T> int B<T>::x = f();
+ template struct __declspec(dllimport) B<int>;
+ USEVAR(B<int>::x);
+ // MSC-DAG: @"?x@?$B@H@PR19933@@2HA" = external dllimport global i32
+
+ constexpr int g() { return 42; }
+ template <typename T> struct C { static int x; };
+ template <typename T> int C<T>::x = g();
+ template struct __declspec(dllimport) C<int>;
+ USEVAR(C<int>::x);
+ // MSC-DAG: @"?x@?$C@H@PR19933@@2HA" = external dllimport global i32
+
+ template <int I> struct D { static int x, y; };
+ template <int I> int D<I>::x = I + 1;
+ template <int I> int D<I>::y = I + f();
+ template struct __declspec(dllimport) D<42>;
+ USEVAR(D<42>::x);
+ USEVAR(D<42>::y);
+ // MSC-DAG: @"?x@?$D@$0CK@@PR19933@@2HA" = external dllimport global i32
+ // MSC-DAG: @"?y@?$D@$0CK@@PR19933@@2HA" = external dllimport global i32
+}
+
+namespace PR21355 {
+ struct __declspec(dllimport) S {
+ virtual ~S();
+ };
+ S::~S() {}
+
+ // S::~S is a key function, so we would ordinarily emit a strong definition for
+ // the vtable. However, S is imported, so the vtable should be too.
+
+ // GNU-DAG: @_ZTVN7PR213551SE = available_externally dllimport unnamed_addr constant { [4 x i8*] }
+}
+
+namespace PR21366 {
+ struct __declspec(dllimport) S {
+ void outOfLineMethod();
+ void inlineMethod() {}
+ inline void anotherInlineMethod();
+ void outOfClassInlineMethod();
+ };
+ void S::anotherInlineMethod() {}
+ inline void S::outOfClassInlineMethod() {}
+}
+
+namespace PR27319 {
+ // Make sure we don't assert due to not having checked for operator delete on
+ // the destructor.
+ template <typename> struct A {
+ virtual ~A() = default;
+ };
+ extern template struct __declspec(dllimport) A<int>;
+ void f() { new A<int>(); }
+ // MO1-DAG: @"??_S?$A@H@PR27319@@6B@" = linkonce_odr unnamed_addr constant { [1 x i8*] }
+}
+
+// MS ignores DLL attributes on partial specializations.
+template <typename T> struct PartiallySpecializedClassTemplate {};
+template <typename T> struct __declspec(dllimport) PartiallySpecializedClassTemplate<T*> { void f(); };
+USEMEMFUNC(PartiallySpecializedClassTemplate<void*>, f);
+// M32-DAG: declare dso_local x86_thiscallcc void @"?f@?$PartiallySpecializedClassTemplate@PAX@@QAEXXZ"
+// G32-DAG: declare dllimport x86_thiscallcc void @_ZN33PartiallySpecializedClassTemplateIPvE1fEv
+
+// Attributes on explicit specializations are honored.
+template <typename T> struct ExplicitlySpecializedClassTemplate {};
+template <> struct __declspec(dllimport) ExplicitlySpecializedClassTemplate<void*> { void f(); };
+USEMEMFUNC(ExplicitlySpecializedClassTemplate<void*>, f);
+// M32-DAG: declare dllimport x86_thiscallcc void @"?f@?$ExplicitlySpecializedClassTemplate@PAX@@QAEXXZ"
+// G32-DAG: declare dllimport x86_thiscallcc void @_ZN34ExplicitlySpecializedClassTemplateIPvE1fEv
+
+// MS inherits DLL attributes to partial specializations.
+template <typename T> struct __declspec(dllimport) PartiallySpecializedImportedClassTemplate {};
+template <typename T> struct PartiallySpecializedImportedClassTemplate<T*> { void f() {} };
+USEMEMFUNC(PartiallySpecializedImportedClassTemplate<void*>, f);
+// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"?f@?$PartiallySpecializedImportedClassTemplate@PAX@@QAEXXZ"
+// G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN41PartiallySpecializedImportedClassTemplateIPvE1fEv
+
+// Attributes on the instantiation take precedence over attributes on the template.
+template <typename T> struct __declspec(dllexport) ExplicitlyInstantiatedWithDifferentAttr { void f() {} };
+template struct __declspec(dllimport) ExplicitlyInstantiatedWithDifferentAttr<int>;
+USEMEMFUNC(ExplicitlyInstantiatedWithDifferentAttr<int>, f);
+// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"?f@?$ExplicitlyInstantiatedWithDifferentAttr@H@@QAEXXZ"
+
+template <typename T> struct ExplicitInstantiationDeclImportedDefTemplate { void f() {} ExplicitInstantiationDeclImportedDefTemplate() {}};
+extern template struct ExplicitInstantiationDeclImportedDefTemplate<int>;
+template struct __declspec(dllimport) ExplicitInstantiationDeclImportedDefTemplate<int>;
+USECLASS(ExplicitInstantiationDeclImportedDefTemplate<int>);
+USEMEMFUNC(ExplicitInstantiationDeclImportedDefTemplate<int>, f);
+// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"?f@?$ExplicitInstantiationDeclImportedDefTemplate@H@@QAEXXZ"
+// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc %struct.ExplicitInstantiationDeclImportedDefTemplate* @"??0?$ExplicitInstantiationDeclImportedDefTemplate@H@@QAE@XZ"
+// G32-DAG: define weak_odr dso_local x86_thiscallcc void @_ZN44ExplicitInstantiationDeclImportedDefTemplateIiE1fEv
+
+template <typename T> struct __declspec(dllimport) ExplicitInstantiationDeclExportedDefImportedTemplate { void f() {} ExplicitInstantiationDeclExportedDefImportedTemplate() {} };
+extern template struct __declspec(dllimport) ExplicitInstantiationDeclExportedDefImportedTemplate <int>;
+template struct __declspec(dllexport) ExplicitInstantiationDeclExportedDefImportedTemplate<int>;
+USECLASS(ExplicitInstantiationDeclExportedDefImportedTemplate<int>);
+USEMEMFUNC(ExplicitInstantiationDeclExportedDefImportedTemplate<int>, f);
+// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"?f@?$ExplicitInstantiationDeclExportedDefImportedTemplate@H@@QAEXXZ"
+// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc %struct.ExplicitInstantiationDeclExportedDefImportedTemplate* @"??0?$ExplicitInstantiationDeclExportedDefImportedTemplate@H@@QAE@XZ"
+
+template <typename T> struct PR23770BaseTemplate { void f() {} };
+template <typename T> struct PR23770DerivedTemplate : PR23770BaseTemplate<int> {};
+extern template struct PR23770DerivedTemplate<int>;
+template struct __declspec(dllimport) PR23770DerivedTemplate<int>;
+USEMEMFUNC(PR23770BaseTemplate<int>, f);
+// M32-DAG: declare dllimport x86_thiscallcc void @"?f@?$PR23770BaseTemplate@H@@QAEXXZ"
+
+namespace PR27810 {
+ template <class T>
+ struct basic_ostream {
+ struct sentry {
+ sentry() { }
+ void foo() { }
+ };
+ };
+ template class __declspec(dllimport) basic_ostream<char>;
+ // The explicit instantiation definition acts as an explicit instantiation
+ // *declaration*, dllimport is not inherited by the inner class, and no
+ // functions are emitted unless they are used.
+
+ USEMEMFUNC(basic_ostream<char>::sentry, foo);
+ // M32-DAG: define linkonce_odr dso_local x86_thiscallcc void @"?foo@sentry@?$basic_ostream@D@PR27810@@QAEXXZ"
+ // M32-NOT: ??0sentry@?$basic_ostream@D@PR27810@@QAE@XZ
+}
+
+namespace PR27811 {
+ template <class T> struct codecvt {
+ virtual ~codecvt() { }
+ };
+ template class __declspec(dllimport) codecvt<char>;
+
+ // dllimport means this explicit instantiation definition gets treated as a
+ // declaration. Thus, the vtable should not be marked used, and in fact
+ // nothing for this class should be emitted at all since it's not used.
+ // M32-NOT: codecvt
+}
+
+//===----------------------------------------------------------------------===//
+// Classes with template base classes
+//===----------------------------------------------------------------------===//
+
+template <typename T> struct ClassTemplate { void func() {} };
+template <typename T> struct __declspec(dllexport) ExportedClassTemplate { void func(); };
+template <typename T> void ExportedClassTemplate<T>::func() {}
+template <typename T> struct __declspec(dllimport) ImportedClassTemplate { void func(); };
+
+template <typename T> struct ExplicitlySpecializedTemplate { void func() {} };
+template <> struct ExplicitlySpecializedTemplate<int> { void func() {} };
+template <typename T> struct ExplicitlyExportSpecializedTemplate { void func() {} };
+template <> struct __declspec(dllexport) ExplicitlyExportSpecializedTemplate<int> { void func(); };
+void ExplicitlyExportSpecializedTemplate<int>::func() {}
+template <typename T> struct ExplicitlyImportSpecializedTemplate { void func() {} };
+template <> struct __declspec(dllimport) ExplicitlyImportSpecializedTemplate<int> { void func(); };
+
+template <typename T> struct ExplicitlyInstantiatedTemplate { void func() {} };
+template struct ExplicitlyInstantiatedTemplate<int>;
+template <typename T> struct ExplicitlyExportInstantiatedTemplate { void func(); };
+template <typename T> void ExplicitlyExportInstantiatedTemplate<T>::func() {}
+template struct __declspec(dllexport) ExplicitlyExportInstantiatedTemplate<int>;
+template <typename T> struct ExplicitlyImportInstantiatedTemplate { void func(); };
+template struct __declspec(dllimport) ExplicitlyImportInstantiatedTemplate<int>;
+
+
+// MS: ClassTemplate<int> gets imported.
+struct __declspec(dllimport) DerivedFromTemplate : public ClassTemplate<int> {};
+USEMEMFUNC(ClassTemplate<int>, func)
+// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"?func@?$ClassTemplate@H@@QAEXXZ"
+// G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN13ClassTemplateIiE4funcEv
+
+// ImportedTemplate is explicitly imported.
+struct __declspec(dllimport) DerivedFromImportedTemplate : public ImportedClassTemplate<int> {};
+USEMEMFUNC(ImportedClassTemplate<int>, func)
+// M32-DAG: declare dllimport x86_thiscallcc void @"?func@?$ImportedClassTemplate@H@@QAEXXZ"
+// G32-DAG: declare dllimport x86_thiscallcc void @_ZN21ImportedClassTemplateIiE4funcEv
+
+// ExportedTemplate is explicitly exported.
+struct __declspec(dllimport) DerivedFromExportedTemplate : public ExportedClassTemplate<int> {};
+USEMEMFUNC(ExportedClassTemplate<int>, func)
+// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?func@?$ExportedClassTemplate@H@@QAEXXZ"
+// G32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @_ZN21ExportedClassTemplateIiE4funcEv
+
+// Base class already implicitly instantiated without attribute.
+struct DerivedFromTemplateD : public ClassTemplate<double> {};
+struct __declspec(dllimport) DerivedFromTemplateD2 : public ClassTemplate<double> {};
+USEMEMFUNC(ClassTemplate<double>, func)
+// M32-DAG: declare dllimport x86_thiscallcc void @"?func@?$ClassTemplate@N@@QAEXXZ"
+// G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN13ClassTemplateIdE4funcEv
+
+// MS: Base class already instantiated with dfferent attribute.
+struct __declspec(dllexport) DerivedFromTemplateB : public ClassTemplate<bool> {};
+struct __declspec(dllimport) DerivedFromTemplateB2 : public ClassTemplate<bool> {};
+USEMEMFUNC(ClassTemplate<bool>, func)
+// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?func@?$ClassTemplate@_N@@QAEXXZ"
+// G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN13ClassTemplateIbE4funcEv
+
+// Base class already specialized without dll attribute.
+struct __declspec(dllimport) DerivedFromExplicitlySpecializedTemplate : public ExplicitlySpecializedTemplate<int> {};
+USEMEMFUNC(ExplicitlySpecializedTemplate<int>, func)
+// M32-DAG: define linkonce_odr dso_local x86_thiscallcc void @"?func@?$ExplicitlySpecializedTemplate@H@@QAEXXZ"
+// G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN29ExplicitlySpecializedTemplateIiE4funcEv
+
+// Base class alredy specialized with export attribute.
+struct __declspec(dllimport) DerivedFromExplicitlyExportSpecializedTemplate : public ExplicitlyExportSpecializedTemplate<int> {};
+USEMEMFUNC(ExplicitlyExportSpecializedTemplate<int>, func)
+// M32-DAG: define dso_local dllexport x86_thiscallcc void @"?func@?$ExplicitlyExportSpecializedTemplate@H@@QAEXXZ"
+// G32-DAG: define dso_local dllexport x86_thiscallcc void @_ZN35ExplicitlyExportSpecializedTemplateIiE4funcEv
+
+// Base class already specialized with import attribute.
+struct __declspec(dllimport) DerivedFromExplicitlyImportSpecializedTemplate : public ExplicitlyImportSpecializedTemplate<int> {};
+USEMEMFUNC(ExplicitlyImportSpecializedTemplate<int>, func)
+// M32-DAG: declare dllimport x86_thiscallcc void @"?func@?$ExplicitlyImportSpecializedTemplate@H@@QAEXXZ"
+// G32-DAG: declare dllimport x86_thiscallcc void @_ZN35ExplicitlyImportSpecializedTemplateIiE4funcEv
+
+// Base class already instantiated without dll attribute.
+struct __declspec(dllimport) DerivedFromExplicitlyInstantiatedTemplate : public ExplicitlyInstantiatedTemplate<int> {};
+USEMEMFUNC(ExplicitlyInstantiatedTemplate<int>, func)
+// M32-DAG: define weak_odr dso_local x86_thiscallcc void @"?func@?$ExplicitlyInstantiatedTemplate@H@@QAEXXZ"
+// G32-DAG: define weak_odr dso_local x86_thiscallcc void @_ZN30ExplicitlyInstantiatedTemplateIiE4funcEv
+
+// Base class already instantiated with export attribute.
+struct __declspec(dllimport) DerivedFromExplicitlyExportInstantiatedTemplate : public ExplicitlyExportInstantiatedTemplate<int> {};
+USEMEMFUNC(ExplicitlyExportInstantiatedTemplate<int>, func)
+// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?func@?$ExplicitlyExportInstantiatedTemplate@H@@QAEXXZ"
+// G32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @_ZN36ExplicitlyExportInstantiatedTemplateIiE4funcEv
+
+// Base class already instantiated with import attribute.
+struct __declspec(dllimport) DerivedFromExplicitlyImportInstantiatedTemplate : public ExplicitlyImportInstantiatedTemplate<int> {};
+USEMEMFUNC(ExplicitlyImportInstantiatedTemplate<int>, func)
+// M32-DAG: declare dllimport x86_thiscallcc void @"?func@?$ExplicitlyImportInstantiatedTemplate@H@@QAEXXZ"
+// G32-DAG: declare dllimport x86_thiscallcc void @_ZN36ExplicitlyImportInstantiatedTemplateIiE4funcEv
+
+// MS: A dll attribute propagates through multiple levels of instantiation.
+template <typename T> struct TopClass { void func() {} };
+template <typename T> struct MiddleClass : public TopClass<T> { };
+struct __declspec(dllimport) BottomClass : public MiddleClass<int> { };
+USEMEMFUNC(TopClass<int>, func)
+// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"?func@?$TopClass@H@@QAEXXZ"
+// G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN8TopClassIiE4funcEv
+
+template <typename T> struct ExplicitInstantiationDeclTemplateBase { void func() {} };
+extern template struct ExplicitInstantiationDeclTemplateBase<int>;
+struct __declspec(dllimport) DerivedFromExplicitInstantiationDeclTemplateBase : public ExplicitInstantiationDeclTemplateBase<int> {};
+template struct ExplicitInstantiationDeclTemplateBase<int>;
+USEMEMFUNC(ExplicitInstantiationDeclTemplateBase<int>, func)
+// M32-DAG: declare dllimport x86_thiscallcc void @"?func@?$ExplicitInstantiationDeclTemplateBase@H@@QAEXXZ"
+// G32-DAG: define weak_odr dso_local x86_thiscallcc void @_ZN37ExplicitInstantiationDeclTemplateBaseIiE4funcEv
+
+template <typename T> struct ExplicitInstantiationDeclTemplateBase2 { void func() {} };
+extern template struct ExplicitInstantiationDeclTemplateBase2<int>;
+struct __declspec(dllimport) DerivedFromExplicitInstantiationDeclTemplateBase2 : public ExplicitInstantiationDeclTemplateBase2<int> {};
+template struct __declspec(dllexport) ExplicitInstantiationDeclTemplateBase2<int>;
+USEMEMFUNC(ExplicitInstantiationDeclTemplateBase2<int>, func)
+// M32-DAG: declare dllimport x86_thiscallcc void @"?func@?$ExplicitInstantiationDeclTemplateBase2@H@@QAEXXZ"
+// G32-DAG: define weak_odr dso_local x86_thiscallcc void @_ZN38ExplicitInstantiationDeclTemplateBase2IiE4funcEv
+
+namespace pr39496 {
+// Make sure dll attribute are inherited by static locals also in template
+// specializations.
+template <typename> struct __declspec(dllimport) S { int foo() { static int x; return x++; } };
+int foo() { S<int> s; return s.foo(); }
+// MO1-DAG: @"?x@?{{1|2}}??foo@?$S@H@pr39496@@Q{{[A-Z]*}}HXZ@4HA" = available_externally dllimport global i32 0, align 4
+
+template <typename> struct T { int foo() { static int x; return x++; } };
+extern template struct __declspec(dllimport) T<int>;
+int bar() { T<int> t; return t.foo(); }
+// MO1-DAG: @"?x@?{{1|2}}??foo@?$T@H@pr39496@@Q{{[A-Z]*}}HXZ@4HA" = available_externally dllimport global i32 0, align 4
+
+template <typename T> struct __declspec(dllimport) U {
+ void foo() {
+ // Don't inherit dllimport to src before attaching the initializer.
+ static constexpr char src[] = {"hello"};
+ T arr[sizeof(src)];
+ }
+};
+void baz() { U<int> u; u.foo(); } // No diagnostic.
+
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/dso-local-executable.cpp b/src/llvm-project/clang/test/CodeGenCXX/dso-local-executable.cpp
new file mode 100644
index 0000000..ceb649e
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/dso-local-executable.cpp
@@ -0,0 +1,80 @@
+// RUN: %clang_cc1 -triple x86_64-pc-linux -mrelocation-model static -O1 -emit-llvm %s -o - | FileCheck --check-prefix=STATIC %s
+// RUN: %clang_cc1 -triple x86_64-pc-linux -mrelocation-model static -fno-plt -O1 -emit-llvm %s -o - | FileCheck --check-prefix=NOPLT %s
+// RUN: %clang_cc1 -triple x86_64-w64-mingw32 -O1 -emit-llvm %s -o - | FileCheck --check-prefix=MINGW %s
+
+// STATIC-DAG: @_ZTV1C = linkonce_odr dso_local unnamed_addr constant
+// STATIC-DAG: @_ZTS1C = linkonce_odr dso_local constant
+// STATIC-DAG: @_ZTI1C = linkonce_odr dso_local constant
+// STATIC-DAG: @_ZZ14useStaticLocalvE3obj = linkonce_odr dso_local global
+// STATIC-DAG: @_ZGVZN5guard1gEvE1a = linkonce_odr dso_local global
+// STATIC-DAG: define dso_local void @_ZN1CC2Ev(
+// STATIC-DAG: define dso_local void @_ZN1CC1Ev(
+// STATIC-DAG: define linkonce_odr dso_local void @_ZN1C3fooEv(
+
+// NOPLT-DAG: @_ZTV1C = linkonce_odr dso_local unnamed_addr constant
+// NOPLT-DAG: @_ZTS1C = linkonce_odr dso_local constant
+// NOPLT-DAG: @_ZTI1C = linkonce_odr dso_local constant
+// NOPLT-DAG: @_ZZ14useStaticLocalvE3obj = linkonce_odr dso_local global
+// NOPLT-DAG: @_ZGVZN5guard1gEvE1a = linkonce_odr dso_local global
+// NOPLT-DAG: define dso_local void @_ZN1CC2Ev(
+// NOPLT-DAG: define dso_local void @_ZN1CC1Ev(
+// NOPLT-DAG: define linkonce_odr dso_local void @_ZN1C3fooEv(
+
+// MINGW-DAG: @_ZTV1C = linkonce_odr dso_local unnamed_addr constant
+// MINGW-DAG: @_ZTS1C = linkonce_odr dso_local constant
+// MINGW-DAG: @_ZTI1C = linkonce_odr dso_local constant
+// MINGW-DAG: @_ZZ14useStaticLocalvE3obj = linkonce_odr dso_local global
+// MINGW-DAG: @_ZGVZN5guard1gEvE1a = linkonce_odr dso_local global
+// MINGW-DAG: define dso_local void @_ZN1CC2Ev(
+// MINGW-DAG: define dso_local void @_ZN1CC1Ev(
+// MINGW-DAG: define linkonce_odr dso_local void @_ZN1C3fooEv(
+
+struct C {
+ C();
+ virtual void foo() {}
+};
+C::C() {}
+
+struct HasVTable {
+ virtual void f();
+};
+inline HasVTable &useStaticLocal() {
+ static HasVTable obj;
+ return obj;
+}
+void useit() {
+ useStaticLocal();
+}
+
+namespace guard {
+int f();
+inline int g() {
+ static int a = f();
+ return a;
+}
+int h() {
+ return g();
+}
+} // namespace guard
+
+
+// STATIC-DAG: @_ZN5test23barIiE1xE = available_externally dso_local constant i32
+// STATIC-DAG: define available_externally dso_local void @_ZN5test23barIcEC1Ev(
+// NOPLT-DAG: @_ZN5test23barIiE1xE = available_externally dso_local constant i32
+// NOPLT-DAG: define available_externally void @_ZN5test23barIcEC1Ev(
+// MINGW-DAG: @_ZN5test23barIiE1xE = available_externally constant i32
+// MINGW-DAG: define available_externally dso_local void @_ZN5test23barIcEC1Ev(
+namespace test2 {
+void foo();
+template <typename T>
+struct bar {
+ virtual void zed();
+ static const int x = 42;
+ bar() { foo(); }
+};
+extern template class bar<char>;
+bar<char> abc;
+const int *getX() {
+ return &bar<int>::x;
+}
+} // namespace test2
diff --git a/src/llvm-project/clang/test/CodeGenCXX/duplicate-mangled-name.cpp b/src/llvm-project/clang/test/CodeGenCXX/duplicate-mangled-name.cpp
new file mode 100644
index 0000000..741e021
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/duplicate-mangled-name.cpp
@@ -0,0 +1,79 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm-only %s -verify -DTEST1
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm-only %s -verify -DTEST2 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm-only %s -verify -DTEST3
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm-only %s -verify -DTEST4
+
+#ifdef TEST1
+
+// rdar://15522601
+class MyClass {
+ static void meth();
+};
+void MyClass::meth() { } // expected-note {{previous}}
+extern "C" {
+ void _ZN7MyClass4methEv() { } // expected-error {{definition with same mangled name '_ZN7MyClass4methEv' as another definition}}
+}
+
+#elif TEST2
+
+// expected-no-diagnostics
+
+// We expect no warnings here, as there is only declaration of _ZN1TD1Ev
+// function, no definitions.
+extern "C" void _ZN1TD1Ev();
+struct T {
+ ~T() {}
+};
+
+// We expect no warnings here, as there is only declaration of _ZN2nm3abcE
+// global, no definitions.
+extern "C" {
+ int _ZN2nm3abcE;
+}
+
+namespace nm {
+ float abc = 2;
+}
+// CHECK: @_ZN2nm3abcE = {{(dso_local )?}}global float
+
+float foo() {
+ _ZN1TD1Ev();
+// CHECK: call void bitcast ({{.*}} (%struct.T*)* @_ZN1TD1Ev to void ()*)()
+ T t;
+// CHECK: call {{.*}} @_ZN1TD1Ev(%struct.T* %t)
+ return _ZN2nm3abcE + nm::abc;
+}
+
+#elif TEST3
+
+extern "C" void _ZN2T2D2Ev() {}; // expected-note {{previous definition is here}}
+
+struct T2 {
+ ~T2() {} // expected-error {{definition with same mangled name '_ZN2T2D2Ev' as another definition}}
+};
+
+void foo() {
+ _ZN2T2D2Ev();
+ T2 t;
+}
+
+#elif TEST4
+
+extern "C" {
+ int _ZN2nm3abcE = 1; // expected-note {{previous definition is here}}
+}
+
+namespace nm {
+ float abc = 2; // expected-error {{definition with same mangled name '_ZN2nm3abcE' as another definition}}
+}
+
+float foo() {
+ return _ZN2nm3abcE + nm::abc;
+}
+
+#else
+
+#error Unknown test
+
+#endif
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/dynamic-cast-always-null.cpp b/src/llvm-project/clang/test/CodeGenCXX/dynamic-cast-always-null.cpp
new file mode 100644
index 0000000..db4346f
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/dynamic-cast-always-null.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -I%S %s -triple x86_64-apple-darwin10 -emit-llvm -fcxx-exceptions -fexceptions -std=c++11 -o - | FileCheck %s
+struct A { virtual ~A(); };
+struct B final : A { };
+struct C { virtual ~C(); int c; };
+
+// CHECK: @_Z1fP1B
+C *f(B* b) {
+ // CHECK-NOT: call i8* @__dynamic_cast
+ // CHECK: ret %struct.C* null
+ return dynamic_cast<C*>(b);
+}
+
+// CHECK: @_Z1fR1B
+C &f(B& b) {
+ // CHECK-NOT: call i8* @__dynamic_cast
+ // CHECK: call void @__cxa_bad_cast() [[NR:#[0-9]+]]
+ // CHECK: ret %struct.C* undef
+ return dynamic_cast<C&>(b);
+}
+
+void dont_crash() {
+ (void) dynamic_cast<void*>((A*)0);
+ (void) dynamic_cast<void*>((B*)0);
+}
+
+// CHECK: attributes [[NR]] = { noreturn }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/dynamic-cast-hint.cpp b/src/llvm-project/clang/test/CodeGenCXX/dynamic-cast-hint.cpp
new file mode 100644
index 0000000..f88d39d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/dynamic-cast-hint.cpp
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin12 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin12 -emit-llvm -std=c++98 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin12 -emit-llvm -std=c++11 -o - %s | FileCheck %s
+
+class A { protected: virtual ~A() {} };
+class B { protected: virtual ~B() {} };
+
+class C : A { char x; };
+class D : public A { short y; };
+class E : public A, public B { int z; };
+class F : public virtual A { long long w; };
+class G : virtual A { long long w; };
+
+class H : public E { int a; };
+class I : public F { char b; };
+
+class J : public H { char q; };
+class K : public C, public B { char q; };
+
+class XA : public A { };
+class XB : public A { };
+class XC : public virtual A { };
+class X : public XA, public XB, public XC { };
+
+void test(A *a, B *b) {
+ volatile C *ac = dynamic_cast<C *>(a);
+// CHECK: i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*), i8* bitcast ({ i8*, i8*, i32, i32, i8*, i64 }* @_ZTI1C to i8*), i64 -2)
+ volatile D *ad = dynamic_cast<D *>(a);
+// CHECK: i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*), i8* bitcast ({ i8*, i8*, i8* }* @_ZTI1D to i8*), i64 0)
+ volatile E *ae = dynamic_cast<E *>(a);
+// CHECK: i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*), i8* bitcast ({ i8*, i8*, i32, i32, i8*, i64, i8*, i64 }* @_ZTI1E to i8*), i64 0)
+ volatile F *af = dynamic_cast<F *>(a);
+// CHECK: i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*), i8* bitcast ({ i8*, i8*, i32, i32, i8*, i64 }* @_ZTI1F to i8*), i64 -1)
+ volatile G *ag = dynamic_cast<G *>(a);
+// CHECK: i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*), i8* bitcast ({ i8*, i8*, i32, i32, i8*, i64 }* @_ZTI1G to i8*), i64 -2)
+ volatile H *ah = dynamic_cast<H *>(a);
+// CHECK: i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*), i8* bitcast ({ i8*, i8*, i8* }* @_ZTI1H to i8*), i64 0)
+ volatile I *ai = dynamic_cast<I *>(a);
+// CHECK: i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*), i8* bitcast ({ i8*, i8*, i8* }* @_ZTI1I to i8*), i64 -1)
+ volatile J *aj = dynamic_cast<J *>(a);
+// CHECK: i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*), i8* bitcast ({ i8*, i8*, i8* }* @_ZTI1J to i8*), i64 0)
+ volatile K *ak = dynamic_cast<K *>(a);
+// CHECK: i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*), i8* bitcast ({ i8*, i8*, i32, i32, i8*, i64, i8*, i64 }* @_ZTI1K to i8*), i64 -2)
+ volatile X *ax = dynamic_cast<X *>(a);
+// CHECK: i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*), i8* bitcast ({ i8*, i8*, i32, i32, i8*, i64, i8*, i64, i8*, i64 }* @_ZTI1X to i8*), i64 -1)
+
+ volatile E *be = dynamic_cast<E *>(b);
+// CHECK: i8* bitcast ({ i8*, i8* }* @_ZTI1B to i8*), i8* bitcast ({ i8*, i8*, i32, i32, i8*, i64, i8*, i64 }* @_ZTI1E to i8*), i64 8)
+ volatile G *bg = dynamic_cast<G *>(b);
+// CHECK: i8* bitcast ({ i8*, i8* }* @_ZTI1B to i8*), i8* bitcast ({ i8*, i8*, i32, i32, i8*, i64 }* @_ZTI1G to i8*), i64 -2)
+ volatile J *bj = dynamic_cast<J *>(b);
+// CHECK: i8* bitcast ({ i8*, i8* }* @_ZTI1B to i8*), i8* bitcast ({ i8*, i8*, i8* }* @_ZTI1J to i8*), i64 8)
+ volatile K *bk = dynamic_cast<K *>(b);
+// CHECK: i8* bitcast ({ i8*, i8* }* @_ZTI1B to i8*), i8* bitcast ({ i8*, i8*, i32, i32, i8*, i64, i8*, i64 }* @_ZTI1K to i8*), i64 16)
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/dynamic-cast.cpp b/src/llvm-project/clang/test/CodeGenCXX/dynamic-cast.cpp
new file mode 100644
index 0000000..9467f3e
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/dynamic-cast.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -I%S %s -triple x86_64-apple-darwin10 -emit-llvm -fcxx-exceptions -fexceptions -o - | FileCheck %s
+struct A { virtual void f(); };
+struct B : A { };
+
+// CHECK: {{define.*@_Z1fP1A}}
+// CHECK-SAME: personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+B fail;
+const B& f(A *a) {
+ try {
+ // CHECK: call i8* @__dynamic_cast
+ // CHECK: br i1
+ // CHECK: invoke void @__cxa_bad_cast() [[NR:#[0-9]+]]
+ dynamic_cast<const B&>(*a);
+ } catch (...) {
+ // CHECK: landingpad { i8*, i32 }
+ // CHECK-NEXT: catch i8* null
+ }
+ return fail;
+}
+
+// CHECK: declare i8* @__dynamic_cast(i8*, i8*, i8*, i64) [[NUW_RO:#[0-9]+]]
+
+// CHECK: attributes [[NUW_RO]] = { nounwind readonly }
+// CHECK: attributes [[NR]] = { noreturn }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/dynamic_cast-no-rtti.cpp b/src/llvm-project/clang/test/CodeGenCXX/dynamic_cast-no-rtti.cpp
new file mode 100644
index 0000000..58834a5
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/dynamic_cast-no-rtti.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -emit-llvm %s -verify -fno-rtti -triple %itanium_abi_triple -o - | FileCheck %s
+// expected-no-diagnostics
+
+struct A {
+ virtual ~A(){};
+};
+
+struct B : public A {
+ B() : A() {}
+};
+
+// An upcast can be resolved statically and can be used with -fno-rtti, iff it
+// does not use runtime support.
+A *upcast(B *b) {
+ return dynamic_cast<A *>(b);
+// CHECK-LABEL: define {{.*}}%struct.A* @_Z6upcastP1B
+// CHECK-NOT: call {{.*}}i8* @__dynamic_cast
+}
+
+// A NoOp dynamic_cast can be used with -fno-rtti iff it does not use
+// runtime support.
+B *samecast(B *b) {
+ return dynamic_cast<B *>(b);
+// CHECK-LABEL: define {{.*}}%struct.B* @_Z8samecastP1B
+// CHECK-NOT: call {{.*}}i8* @__dynamic_cast
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/eh-aggregate-copy-destroy.cpp b/src/llvm-project/clang/test/CodeGenCXX/eh-aggregate-copy-destroy.cpp
new file mode 100644
index 0000000..9f0f36c
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/eh-aggregate-copy-destroy.cpp
@@ -0,0 +1,39 @@
+// Check that in case of copying an array of memcpy-able objects, their
+// destructors will be called if an exception is thrown.
+//
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fexceptions -fcxx-exceptions -O0 -fno-elide-constructors -std=c++98 -emit-llvm %s -o - | FileCheck -check-prefix=CHECK -check-prefix=CHECK98 %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fexceptions -fcxx-exceptions -O0 -fno-elide-constructors -std=c++11 -emit-llvm %s -o - | FileCheck -check-prefix=CHECK -check-prefix=CHECK11 %s
+
+struct ImplicitCopy {
+ int x;
+ ImplicitCopy() { x = 10; }
+ ~ImplicitCopy() { x = 20; }
+};
+
+struct ThrowCopy {
+ ThrowCopy() {}
+ ThrowCopy(const ThrowCopy &) { throw 1; }
+};
+
+struct Container {
+ ImplicitCopy b[2];
+ ThrowCopy c;
+};
+
+int main () {
+ try {
+ Container c1;
+ // CHECK_LABEL: main
+ // CHECK-NOT: call void @_ZN9ThrowCopyC1ERKS_
+ // CHECK: invoke void @_ZN9ThrowCopyC1ERKS_
+ // CHECK98: invoke void @_ZN12ImplicitCopyD1Ev
+ // CHECK11: call void @_ZN12ImplicitCopyD1Ev
+ Container c2(c1);
+ }
+ catch (...) {
+ return 1;
+ }
+
+ return 0;
+}
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/eh-aggregated-inits-unwind.cpp b/src/llvm-project/clang/test/CodeGenCXX/eh-aggregated-inits-unwind.cpp
new file mode 100644
index 0000000..9772564
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/eh-aggregated-inits-unwind.cpp
@@ -0,0 +1,47 @@
+// Check that destructors of memcpy-able struct members are called properly
+// during stack unwinding after an exception.
+//
+// Check that destructor's argument (address of member to be destroyed) is
+// obtained by taking offset from struct, not by bitcasting pointers.
+//
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -O0 -fno-elide-constructors -emit-llvm %s -o - | FileCheck %s
+
+struct ImplicitCopy {
+ int id;
+ ImplicitCopy() { id = 10; }
+ ~ImplicitCopy() { id = 20; }
+};
+
+struct ThrowCopy {
+ int id;
+ ThrowCopy() { id = 15; }
+ ThrowCopy(const ThrowCopy &x) {
+ id = 25;
+ throw 1;
+ }
+ ~ThrowCopy() { id = 35; }
+};
+
+struct Container {
+ int id;
+ ImplicitCopy o1;
+ ThrowCopy o2;
+
+ Container() { id = 1000; }
+ ~Container() { id = 2000; }
+};
+
+int main() {
+ try {
+ Container c1;
+ // CHECK-LABEL: main
+ // CHECK: %{{.+}} = getelementptr inbounds %struct.Container, %struct.Container* %{{.+}}, i32 0, i32 1
+ // CHECK-NOT: %{{.+}} = bitcast %struct.Container* %{{.+}} to %struct.ImplicitCopy*
+ Container c2(c1);
+
+ return 2;
+ } catch (...) {
+ return 1;
+ }
+ return 0;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/eh-aggregated-inits.cpp b/src/llvm-project/clang/test/CodeGenCXX/eh-aggregated-inits.cpp
new file mode 100644
index 0000000..cb34b65
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/eh-aggregated-inits.cpp
@@ -0,0 +1,46 @@
+// Check that initialization of the only one memcpy-able struct member will not
+// be performed twice after successful non-trivial initializtion of the second
+// member.
+//
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -O0 -fno-elide-constructors -emit-llvm %s -o - | FileCheck %s
+
+int globId = 0;
+
+struct ImplicitCopy {
+ int id;
+
+ ImplicitCopy() { id = 10; }
+ ~ImplicitCopy() { id = 20; }
+};
+
+struct ExplicitCopy {
+ int id;
+
+ ExplicitCopy() { id = 15; }
+ ExplicitCopy(const ExplicitCopy &x) { id = 25; }
+ ~ExplicitCopy() { id = 35; }
+};
+
+struct Container {
+ ImplicitCopy o1; // memcpy-able member.
+ ExplicitCopy o2; // non-trivial initialization.
+
+ Container() { globId = 1000; }
+ ~Container() { globId = 2000; }
+};
+
+int main() {
+ try {
+ Container c1;
+ // CHECK-DAG: call void @llvm.memcpy
+ // CHECK-DAG: declare void @llvm.memcpy
+ // CHECK-NOT: @llvm.memcpy
+ Container c2(c1);
+
+ return 2;
+ }
+ catch (...) {
+ return 1;
+ }
+ return 0;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/eh.cpp b/src/llvm-project/clang/test/CodeGenCXX/eh.cpp
new file mode 100644
index 0000000..d393ee1
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/eh.cpp
@@ -0,0 +1,474 @@
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -triple x86_64-apple-darwin -std=c++11 -emit-llvm %s -o - \
+// RUN: | FileCheck %s
+
+struct test1_D {
+ double d;
+} d1;
+
+void test1() {
+ throw d1;
+}
+
+// CHECK-LABEL: define void @_Z5test1v()
+// 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* align 16 [[EXN2]], i8* align 8 bitcast ([[DSTAR]] @d1 to i8*), i64 8, i1 false)
+// CHECK-NEXT: call void @__cxa_throw(i8* [[EXNOBJ]], i8* bitcast ({ i8*, i8* }* @_ZTI7test1_D to i8*), i8* null) [[NR:#[0-9]+]]
+// CHECK-NEXT: unreachable
+
+
+struct test2_D {
+ test2_D(const test2_D&o);
+ test2_D();
+ virtual void bar() { }
+ int i; int j;
+} d2;
+
+void test2() {
+ throw d2;
+}
+
+// CHECK-LABEL: define void @_Z5test2v()
+// CHECK: [[EXNVAR:%.*]] = alloca i8*
+// CHECK-NEXT: [[SELECTORVAR:%.*]] = alloca i32
+// CHECK-NEXT: [[EXNOBJ:%.*]] = call i8* @__cxa_allocate_exception(i64 16)
+// CHECK-NEXT: [[EXN:%.*]] = bitcast i8* [[EXNOBJ]] to [[DSTAR:%[^*]*\*]]
+// CHECK-NEXT: invoke void @_ZN7test2_DC1ERKS_([[DSTAR]] [[EXN]], [[DSTAR]] dereferenceable({{[0-9]+}}) @d2)
+// CHECK-NEXT: to label %[[CONT:.*]] unwind label %{{.*}}
+// : [[CONT]]: (can't check this in Release-Asserts builds)
+// CHECK: call void @__cxa_throw(i8* [[EXNOBJ]], i8* bitcast ({{.*}}* @_ZTI7test2_D to i8*), i8* null) [[NR]]
+// CHECK-NEXT: unreachable
+
+
+struct test3_D {
+ test3_D() { }
+ test3_D(volatile test3_D&o);
+ virtual void bar();
+};
+
+void test3() {
+ throw (volatile test3_D *)0;
+}
+
+// CHECK-LABEL: define void @_Z5test3v()
+// 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 ({ i8*, i8*, i32, i8* }* @_ZTIPV7test3_D to i8*), i8* null) [[NR]]
+// CHECK-NEXT: unreachable
+
+
+void test4() {
+ throw;
+}
+
+// CHECK-LABEL: define void @_Z5test4v()
+// CHECK: call void @__cxa_rethrow() [[NR]]
+// CHECK-NEXT: unreachable
+
+
+// rdar://problem/7696549
+namespace test5 {
+ struct A {
+ A();
+ A(const A&);
+ ~A();
+ };
+
+ void test() {
+ try { throw A(); } catch (A &x) {}
+ }
+// CHECK-LABEL: define void @_ZN5test54testEv()
+// CHECK: [[EXNOBJ:%.*]] = call i8* @__cxa_allocate_exception(i64 1)
+// CHECK: [[EXNCAST:%.*]] = bitcast i8* [[EXNOBJ]] to [[A:%[^*]*]]*
+// CHECK-NEXT: invoke void @_ZN5test51AC1Ev([[A]]* [[EXNCAST]])
+// CHECK: invoke void @__cxa_throw(i8* [[EXNOBJ]], i8* bitcast ({{.*}}* @_ZTIN5test51AE to i8*), i8* bitcast (void ([[A]]*)* @_ZN5test51AD1Ev to i8*)) [[NR]]
+// CHECK-NEXT: to label {{%.*}} unwind label %[[HANDLER:[^ ]*]]
+// : [[HANDLER]]: (can't check this in Release-Asserts builds)
+// CHECK: {{%.*}} = call i32 @llvm.eh.typeid.for(i8* bitcast ({{.*}}* @_ZTIN5test51AE to i8*))
+}
+
+namespace test6 {
+ template <class T> struct allocator {
+ ~allocator() throw() { }
+ };
+
+ void foo() {
+ allocator<int> a;
+ }
+}
+
+// PR7127
+namespace test7 {
+// CHECK-LABEL: define i32 @_ZN5test73fooEv()
+// CHECK-SAME: personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ int foo() {
+// CHECK: [[CAUGHTEXNVAR:%.*]] = alloca i8*
+// CHECK-NEXT: [[SELECTORVAR:%.*]] = alloca i32
+// CHECK-NEXT: [[INTCATCHVAR:%.*]] = alloca i32
+ try {
+ try {
+// CHECK-NEXT: [[EXNALLOC:%.*]] = call i8* @__cxa_allocate_exception
+// CHECK-NEXT: bitcast i8* [[EXNALLOC]] to i32*
+// CHECK-NEXT: store i32 1, i32*
+// CHECK-NEXT: invoke void @__cxa_throw(i8* [[EXNALLOC]], i8* bitcast (i8** @_ZTIi to i8*), i8* null
+ throw 1;
+ }
+
+// CHECK: [[CAUGHTVAL:%.*]] = landingpad { i8*, i32 }
+// CHECK-NEXT: catch i8* bitcast (i8** @_ZTIi to i8*)
+// CHECK-NEXT: catch i8* null
+// CHECK-NEXT: [[CAUGHTEXN:%.*]] = extractvalue { i8*, i32 } [[CAUGHTVAL]], 0
+// CHECK-NEXT: store i8* [[CAUGHTEXN]], i8** [[CAUGHTEXNVAR]]
+// CHECK-NEXT: [[SELECTOR:%.*]] = extractvalue { i8*, i32 } [[CAUGHTVAL]], 1
+// CHECK-NEXT: store i32 [[SELECTOR]], i32* [[SELECTORVAR]]
+// CHECK-NEXT: br label
+// CHECK: [[SELECTOR:%.*]] = load i32, i32* [[SELECTORVAR]]
+// CHECK-NEXT: [[T0:%.*]] = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*))
+// CHECK-NEXT: icmp eq i32 [[SELECTOR]], [[T0]]
+// CHECK-NEXT: br i1
+// CHECK: [[T0:%.*]] = load i8*, i8** [[CAUGHTEXNVAR]]
+// CHECK-NEXT: [[T1:%.*]] = call i8* @__cxa_begin_catch(i8* [[T0]])
+// CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to i32*
+// CHECK-NEXT: [[T3:%.*]] = load i32, i32* [[T2]]
+// CHECK-NEXT: store i32 [[T3]], i32* {{%.*}}, align 4
+// CHECK-NEXT: invoke void @__cxa_rethrow
+ catch (int) {
+ throw;
+ }
+ }
+// CHECK: [[CAUGHTVAL:%.*]] = landingpad { i8*, i32 }
+// CHECK-NEXT: catch i8* null
+// CHECK-NEXT: [[CAUGHTEXN:%.*]] = extractvalue { i8*, i32 } [[CAUGHTVAL]], 0
+// CHECK-NEXT: store i8* [[CAUGHTEXN]], i8** [[CAUGHTEXNVAR]]
+// CHECK-NEXT: [[SELECTOR:%.*]] = extractvalue { i8*, i32 } [[CAUGHTVAL]], 1
+// CHECK-NEXT: store i32 [[SELECTOR]], i32* [[SELECTORVAR]]
+// CHECK-NEXT: call void @__cxa_end_catch()
+// CHECK-NEXT: br label
+// CHECK: load i8*, i8** [[CAUGHTEXNVAR]]
+// CHECK-NEXT: call i8* @__cxa_begin_catch
+// CHECK-NEXT: call void @__cxa_end_catch
+ catch (...) {
+ }
+// CHECK: ret i32 0
+ return 0;
+ }
+}
+
+// Ordering of destructors in a catch handler.
+namespace test8 {
+ struct A { A(const A&); ~A(); };
+ void bar();
+
+ // CHECK-LABEL: define void @_ZN5test83fooEv()
+ void foo() {
+ try {
+ // CHECK: invoke void @_ZN5test83barEv()
+ bar();
+ } catch (A a) {
+ // CHECK: call i8* @__cxa_get_exception_ptr
+ // CHECK-NEXT: bitcast
+ // CHECK-NEXT: invoke void @_ZN5test81AC1ERKS0_(
+ // CHECK: call i8* @__cxa_begin_catch
+ // CHECK-NEXT: call void @_ZN5test81AD1Ev(
+ // CHECK: call void @__cxa_end_catch()
+ // CHECK: ret void
+ }
+ }
+}
+
+// Constructor function-try-block must rethrow on fallthrough.
+// rdar://problem/7696603
+namespace test9 {
+ void opaque();
+
+ struct A { A(); };
+
+
+ // CHECK-LABEL: define void @_ZN5test91AC2Ev(%"struct.test9::A"* %this) unnamed_addr
+ // CHECK-SAME: personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ A::A() try {
+ // CHECK: invoke void @_ZN5test96opaqueEv()
+ opaque();
+ } catch (int x) {
+ // CHECK: landingpad { i8*, i32 }
+ // CHECK-NEXT: catch i8* bitcast (i8** @_ZTIi to i8*)
+
+ // CHECK: call i8* @__cxa_begin_catch
+ // CHECK: invoke void @_ZN5test96opaqueEv()
+ // CHECK: invoke void @__cxa_rethrow()
+
+ // CHECK-LABEL: define void @_ZN5test91AC1Ev(%"struct.test9::A"* %this) unnamed_addr
+ // CHECK: call void @_ZN5test91AC2Ev
+ // CHECK-NEXT: ret void
+ opaque();
+ }
+}
+
+// __cxa_end_catch can throw for some kinds of caught exceptions.
+namespace test10 {
+ void opaque();
+
+ struct A { ~A(); };
+ struct B { int x; };
+
+ // CHECK-LABEL: define void @_ZN6test103fooEv()
+ void foo() {
+ A a; // force a cleanup context
+
+ try {
+ // CHECK: invoke void @_ZN6test106opaqueEv()
+ opaque();
+ } catch (int i) {
+ // CHECK: call i8* @__cxa_begin_catch
+ // CHECK-NEXT: bitcast
+ // CHECK-NEXT: load i32, i32*
+ // CHECK-NEXT: store i32
+ // CHECK-NEXT: call void @__cxa_end_catch() [[NUW:#[0-9]+]]
+ } catch (B a) {
+ // CHECK: call i8* @__cxa_begin_catch
+ // CHECK-NEXT: bitcast
+ // CHECK-NEXT: bitcast
+ // CHECK-NEXT: bitcast
+ // CHECK-NEXT: call void @llvm.memcpy
+ // CHECK-NEXT: invoke void @__cxa_end_catch()
+ } catch (...) {
+ // CHECK: call i8* @__cxa_begin_catch
+ // CHECK-NEXT: invoke void @__cxa_end_catch()
+ }
+
+ // CHECK: call void @_ZN6test101AD1Ev(
+ }
+}
+
+// __cxa_begin_catch returns pointers by value, even when catching by reference
+// <rdar://problem/8212123>
+namespace test11 {
+ void opaque();
+
+ // CHECK-LABEL: define void @_ZN6test113fooEv()
+ void foo() {
+ try {
+ // CHECK: invoke void @_ZN6test116opaqueEv()
+ opaque();
+ } catch (int**&p) {
+ // CHECK: [[EXN:%.*]] = load i8*, i8**
+ // CHECK-NEXT: call i8* @__cxa_begin_catch(i8* [[EXN]]) [[NUW]]
+ // CHECK-NEXT: [[ADJ1:%.*]] = getelementptr i8, i8* [[EXN]], i32 32
+ // CHECK-NEXT: [[ADJ2:%.*]] = bitcast i8* [[ADJ1]] to i32***
+ // CHECK-NEXT: store i32*** [[ADJ2]], i32**** [[P:%.*]]
+ // CHECK-NEXT: call void @__cxa_end_catch() [[NUW]]
+ }
+ }
+
+ struct A {};
+
+ // CHECK-LABEL: define void @_ZN6test113barEv()
+ void bar() {
+ try {
+ // CHECK: [[EXNSLOT:%.*]] = alloca i8*
+ // CHECK-NEXT: [[SELECTORSLOT:%.*]] = alloca i32
+ // CHECK-NEXT: [[P:%.*]] = alloca [[A:%.*]]**,
+ // CHECK-NEXT: [[TMP:%.*]] = alloca [[A]]*
+ // CHECK-NEXT: invoke void @_ZN6test116opaqueEv()
+ opaque();
+ } catch (A*&p) {
+ // CHECK: [[EXN:%.*]] = load i8*, i8** [[EXNSLOT]]
+ // CHECK-NEXT: [[ADJ1:%.*]] = call i8* @__cxa_begin_catch(i8* [[EXN]]) [[NUW]]
+ // CHECK-NEXT: [[ADJ2:%.*]] = bitcast i8* [[ADJ1]] to [[A]]*
+ // CHECK-NEXT: store [[A]]* [[ADJ2]], [[A]]** [[TMP]]
+ // CHECK-NEXT: store [[A]]** [[TMP]], [[A]]*** [[P]]
+ // CHECK-NEXT: call void @__cxa_end_catch() [[NUW]]
+ }
+ }
+}
+
+// PR7686
+namespace test12 {
+ struct A { ~A() noexcept(false); };
+ bool opaque(const A&);
+
+ // CHECK-LABEL: define void @_ZN6test124testEv()
+ void test() {
+ // CHECK: [[X:%.*]] = alloca [[A:%.*]],
+ // CHECK: [[EHCLEANUPDEST:%.*]] = alloca i32
+ // CHECK: [[Y:%.*]] = alloca [[A]]
+ // CHECK: [[Z:%.*]] = alloca [[A]]
+ // CHECK: [[CLEANUPDEST:%.*]] = alloca i32
+
+ A x;
+ // CHECK: invoke zeroext i1 @_ZN6test126opaqueERKNS_1AE(
+ if (opaque(x)) {
+ A y;
+ A z;
+
+ // CHECK: invoke void @_ZN6test121AD1Ev([[A]]* [[Z]])
+ // CHECK: invoke void @_ZN6test121AD1Ev([[A]]* [[Y]])
+ // CHECK-NOT: switch
+ goto success;
+ }
+
+ success:
+ bool _ = true;
+
+ // CHECK: call void @_ZN6test121AD1Ev([[A]]* [[X]])
+ // CHECK-NEXT: ret void
+ }
+}
+
+// Reduced from some TableGen code that was causing a self-host crash.
+namespace test13 {
+ struct A { ~A(); };
+
+ void test0(int x) {
+ try {
+ switch (x) {
+ case 0:
+ break;
+ case 1:{
+ A a;
+ break;
+ }
+ default:
+ return;
+ }
+ return;
+ } catch (int x) {
+ }
+ return;
+ }
+
+ void test1(int x) {
+ A y;
+ try {
+ switch (x) {
+ default: break;
+ }
+ } catch (int x) {}
+ }
+}
+
+// rdar://problem/8231514
+namespace test14 {
+ struct A { ~A(); };
+ struct B { ~B(); };
+
+ B b();
+ void opaque();
+
+ void foo() {
+ A a;
+ try {
+ B str = b();
+ opaque();
+ } catch (int x) {
+ }
+ }
+}
+
+// rdar://problem/8231514
+// JumpDests shouldn't get confused by scopes that aren't normal cleanups.
+namespace test15 {
+ struct A { ~A(); };
+
+ bool opaque(int);
+
+ // CHECK-LABEL: define void @_ZN6test153fooEv()
+ void foo() {
+ A a;
+
+ try {
+ // CHECK: [[X:%.*]] = alloca i32
+ // CHECK: store i32 10, i32* [[X]]
+ // CHECK-NEXT: br label
+ // -> while.cond
+ int x = 10;
+
+ while (true) {
+ // CHECK: load i32, i32* [[X]]
+ // CHECK-NEXT: [[COND:%.*]] = invoke zeroext i1 @_ZN6test156opaqueEi
+ // CHECK: br i1 [[COND]]
+ if (opaque(x))
+ // CHECK: br label
+ break;
+
+ // CHECK: br label
+ }
+ // CHECK: br label
+ } catch (int x) { }
+
+ // CHECK: call void @_ZN6test151AD1Ev
+ }
+}
+
+namespace test16 {
+ struct A { A(); ~A() noexcept(false); };
+ struct B { int x; B(const A &); ~B() noexcept(false); };
+ void foo();
+ bool cond();
+
+ // CHECK-LABEL: 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: [[SELECTORSLOT:%.*]] = 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]]* dereferenceable({{[0-9]+}}) [[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, i1* [[EXN_ACTIVE]]
+ // CHECK-NEXT: br i1 [[T0]]
+ // CHECK: [[T1:%.*]] = load i8*, i8** [[EXN_SAVE]]
+ // CHECK-NEXT: call void @__cxa_free_exception(i8* [[T1]])
+ // CHECK-NEXT: br label
+ }
+}
+
+namespace test17 {
+class BaseException {
+private:
+ int a[4];
+public:
+ BaseException() {};
+};
+
+class DerivedException: public BaseException {
+};
+
+int foo() {
+ throw DerivedException();
+ // The alignment passed to memset is 16 on Darwin.
+
+ // CHECK: [[T0:%.*]] = call i8* @__cxa_allocate_exception(i64 16)
+ // CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to %"class.test17::DerivedException"*
+ // CHECK-NEXT: [[T2:%.*]] = bitcast %"class.test17::DerivedException"* [[T1]] to i8*
+ // CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 16 [[T2]], i8 0, i64 16, i1 false)
+}
+}
+
+// CHECK: attributes [[NUW]] = { nounwind }
+// CHECK: attributes [[NR]] = { noreturn }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/elide-call-reference.cpp b/src/llvm-project/clang/test/CodeGenCXX/elide-call-reference.cpp
new file mode 100644
index 0000000..0ce856f
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/elide-call-reference.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 %s -emit-llvm -triple %itanium_abi_triple -o - | FileCheck %s
+// PR5695
+
+struct A { A(const A&); ~A(); };
+A& a();
+void b() {
+ A x = a();
+}
+
+// CHECK: call {{.*}} @_ZN1AC1ERKS_
+// CHECK: call {{.*}} @_ZN1AD1Ev
diff --git a/src/llvm-project/clang/test/CodeGenCXX/empty-classes.cpp b/src/llvm-project/clang/test/CodeGenCXX/empty-classes.cpp
new file mode 100644
index 0000000..5727d59
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/empty-classes.cpp
@@ -0,0 +1,119 @@
+// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -emit-llvm -O3 -o - | FileCheck %s
+
+// CHECK: %"struct.rdar20621065::B" = type { float, float }
+
+struct Empty { };
+
+struct A {
+ explicit A(unsigned a = 0xffffffff) : a(a) { }
+
+ unsigned a;
+};
+
+struct B : A, Empty {
+ B() : A(), Empty() { }
+};
+
+struct C : A, Empty {
+ C() : A(), Empty() { }
+ C(const C& other) : A(0x12345678), Empty(other) { }
+};
+
+struct D : A, Empty {
+ D& operator=(const D& other) {
+ a = 0x87654321;
+ Empty::operator=(other);
+
+ return *this;
+ }
+};
+
+#define CHECK(x) if (!(x)) return __LINE__
+
+// PR7012
+// CHECK-LABEL: define i32 @_Z1fv()
+int f() {
+ B b1;
+
+ // Check that A::a is not overwritten by the Empty default constructor.
+ CHECK(b1.a == 0xffffffff);
+
+ C c1;
+ C c2(c1);
+
+ // Check that A::a has the value set in the C::C copy constructor.
+ CHECK(c2.a == 0x12345678);
+
+ D d1, d2;
+ d2 = d1;
+
+ // Check that A::as has the value set in the D copy assignment operator.
+ CHECK(d2.a == 0x87654321);
+
+ // Success!
+ // CHECK: ret i32 0
+ 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 *, ...);
+
+int main() {
+ int result = f();
+
+ if (result == 0)
+ printf("success!\n");
+ else
+ printf("test on line %d failed!\n", result);
+
+ return result;
+}
+#endif
+
+namespace rdar20621065 {
+ struct A {
+ float array[0];
+ };
+
+ struct B : A {
+ float left;
+ float right;
+ };
+
+ // Type checked at the top of the file.
+ B b;
+};
+
+// This test used to crash when CGRecordLayout::getNonVirtualBaseLLVMFieldNo was called.
+namespace record_layout {
+struct X0 {
+ int x[0];
+};
+
+template<typename>
+struct X2 : X0 {
+};
+
+template<typename>
+struct X3 : X2<int> {
+ X3() : X2<int>() {}
+};
+
+
+void test0() {
+ X3<int>();
+}
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/empty-nontrivially-copyable.cpp b/src/llvm-project/clang/test/CodeGenCXX/empty-nontrivially-copyable.cpp
new file mode 100644
index 0000000..a0977a7
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/empty-nontrivially-copyable.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple armv7-apple-ios -x c++ -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-apple-ios -x c++ -emit-llvm -o - %s | FileCheck %s
+
+// According to the Itanium ABI (3.1.1), types with non-trivial copy
+// constructors passed by value should be passed indirectly, with the caller
+// creating a temporary.
+
+struct Empty;
+
+struct Empty {
+ Empty(const Empty &e);
+ bool check();
+};
+
+bool foo(Empty e) {
+// CHECK: @_Z3foo5Empty(%struct.Empty* %e)
+// CHECK: call {{.*}} @_ZN5Empty5checkEv(%struct.Empty* %e)
+ return e.check();
+}
+
+void caller(Empty &e) {
+// CHECK: @_Z6callerR5Empty(%struct.Empty* dereferenceable({{[0-9]+}}) %e)
+// CHECK: call {{.*}} @_ZN5EmptyC1ERKS_(%struct.Empty* [[NEWTMP:%.*]], %struct.Empty*
+// CHECK: call {{.*}} @_Z3foo5Empty(%struct.Empty* [[NEWTMP]])
+ foo(e);
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/empty-struct-init-list.cpp b/src/llvm-project/clang/test/CodeGenCXX/empty-struct-init-list.cpp
new file mode 100644
index 0000000..33f52ba
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/empty-struct-init-list.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -std=c++11 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -std=c++14 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -std=c++17 -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: struct.a
+typedef struct { } a;
+typedef struct {
+ a b[];
+} c;
+
+// CHECK: {{(dso_local )?}}global %struct.c{{.*}}zeroinitializer
+c d{ };
diff --git a/src/llvm-project/clang/test/CodeGenCXX/empty-union.cpp b/src/llvm-project/clang/test/CodeGenCXX/empty-union.cpp
new file mode 100644
index 0000000..7f3e6cc
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/empty-union.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s
+
+union sigval { };
+union sigval Test1;
+
+union NonPODUnion { ~NonPODUnion(); };
+union NonPODUnion Test2;
diff --git a/src/llvm-project/clang/test/CodeGenCXX/enable_if.cpp b/src/llvm-project/clang/test/CodeGenCXX/enable_if.cpp
new file mode 100644
index 0000000..4e7707a
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/enable_if.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-pc-linux-gnu | FileCheck %s
+
+// Test address-of overloading logic
+int test5(int);
+template <typename T>
+T test5(T) __attribute__((enable_if(1, "better than non-template")));
+
+// CHECK: @_Z5test5IiEUa9enable_ifIXLi1EEET_S0_
+int (*Ptr)(int) = &test5;
+
+// Test itanium mangling for attribute enable_if
+
+// CHECK: _Z5test1Ua9enable_ifIXeqfL0p_Li1EEEi
+void test1(int i) __attribute__((enable_if(i == 1, ""))) {}
+
+void ext();
+// CHECK: _Z5test2Ua9enable_ifIXneadL_Z3extvELi0EEEi
+void test2(int i) __attribute__((enable_if(&ext != 0, ""))) {}
+
+// CHECK: _Z5test3Ua9enable_ifIXeqfL0p_Li1EEXeqfL0p0_Li2EEEii
+void test3(int i, int j) __attribute__((enable_if(i == 1, ""), enable_if(j == 2, ""))) {}
+
+// CHECK: _ZN5test4IdE1fEUa9enable_ifIXeqfL0p_Li1EEXeqfL0p0_Li2EEEi
+template <typename T>
+class test4 {
+ virtual void f(int i, int j) __attribute__((enable_if(i == 1, ""))) __attribute__((enable_if(j == 2, "")));
+};
+
+template class test4<double>;
diff --git a/src/llvm-project/clang/test/CodeGenCXX/enum.cpp b/src/llvm-project/clang/test/CodeGenCXX/enum.cpp
new file mode 100644
index 0000000..3985e96
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/enum.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -emit-llvm-only -verify %s
+// expected-no-diagnostics
+
+enum A { a } __attribute((packed));
+int func(A x) { return x==a; }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/eval-recursive-constant.cpp b/src/llvm-project/clang/test/CodeGenCXX/eval-recursive-constant.cpp
new file mode 100644
index 0000000..608c95d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/eval-recursive-constant.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 %s -emit-llvm-only
+
+extern const int a,b;
+const int a=b,b=a;
+int c() { if (a) return 1; return 0; }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/exception-spec-decay.cpp b/src/llvm-project/clang/test/CodeGenCXX/exception-spec-decay.cpp
new file mode 100644
index 0000000..4928353
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/exception-spec-decay.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions %s -triple=i686-unknown-linux -emit-llvm -o - | FileCheck %s
+typedef int Array[10];
+
+void foo() throw (Array) {
+ throw 0;
+ // CHECK: landingpad
+ // CHECK-NEXT: filter {{.*}} @_ZTIPi
+}
+
+struct S {
+ void foo() throw (S[10]) {
+ throw 0;
+ }
+};
+
+template <typename T>
+struct S2 {
+ void foo() throw (T) {
+ throw 0;
+ }
+};
+
+int main() {
+ S s;
+ s.foo();
+ // CHECK: landingpad
+ // CHECK-NEXT: filter {{.*}} @_ZTIP1S
+
+ S2 <int[10]> s2;
+ s2.foo();
+ // CHECK: landingpad
+ // CHECK-NEXT: filter {{.*}} @_ZTIPi
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/exceptions-cxx-ehsc.cpp b/src/llvm-project/clang/test/CodeGenCXX/exceptions-cxx-ehsc.cpp
new file mode 100644
index 0000000..ae1f463
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/exceptions-cxx-ehsc.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 -fexceptions -fcxx-exceptions -fexternc-nounwind | FileCheck %s
+
+namespace test1 {
+struct Cleanup { ~Cleanup(); };
+extern "C" void never_throws();
+void may_throw();
+
+void caller() {
+ Cleanup x;
+ never_throws();
+ may_throw();
+}
+}
+// CHECK-LABEL: define dso_local void @"?caller@test1@@YAXXZ"(
+// CHECK: call void @never_throws(
+// CHECK: invoke void @"?may_throw@test1@@YAXXZ"(
+
+namespace test2 {
+struct Cleanup { ~Cleanup(); };
+extern "C" void throws_int() throw(int);
+void may_throw();
+
+void caller() {
+ Cleanup x;
+ throws_int();
+ may_throw();
+}
+}
+// CHECK-LABEL: define dso_local void @"?caller@test2@@YAXXZ"(
+// CHECK: invoke void @throws_int(
+// CHECK: invoke void @"?may_throw@test2@@YAXXZ"(
diff --git a/src/llvm-project/clang/test/CodeGenCXX/exceptions-cxx-new.cpp b/src/llvm-project/clang/test/CodeGenCXX/exceptions-cxx-new.cpp
new file mode 100644
index 0000000..4906a7b
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/exceptions-cxx-new.cpp
@@ -0,0 +1,77 @@
+// RUN: %clang_cc1 %s -triple i686-pc-win32 -fms-extensions -fexceptions -fcxx-exceptions -emit-llvm -o - -std=c++11 | FileCheck %s
+
+int f(int);
+
+void test_catch() {
+ try {
+ f(1);
+ } catch (int) {
+ f(2);
+ } catch (double) {
+ f(3);
+ }
+}
+
+// CHECK-LABEL: define dso_local void @"?test_catch@@YAXXZ"(
+// CHECK: invoke i32 @"?f@@YAHH@Z"(i32 1)
+// CHECK: to label %[[NORMAL:.*]] unwind label %[[CATCHSWITCH:.*]]
+
+// CHECK: [[CATCHSWITCH]]
+// CHECK: %[[CATCHSWITCHPAD:.*]] = catchswitch within none [label %[[CATCH_INT:.*]], label %[[CATCH_DOUBLE:.*]]] unwind to caller
+
+// CHECK: [[CATCH_INT]]
+// CHECK: %[[CATCHPAD_INT:.*]] = catchpad within %[[CATCHSWITCHPAD]] [%rtti.TypeDescriptor2* @"??_R0H@8", i32 0, i8* null]
+// CHECK: call i32 @"?f@@YAHH@Z"(i32 2)
+// CHECK: catchret from %[[CATCHPAD_INT]] to label %[[LEAVE_INT_CATCH:.*]]
+
+// CHECK: [[LEAVE_INT_CATCH]]
+// CHECK: br label %[[LEAVE_FUNC:.*]]
+
+// CHECK: [[LEAVE_FUNC]]
+// CHECK: ret void
+
+// CHECK: [[CATCH_DOUBLE]]
+// CHECK: %[[CATCHPAD_DOUBLE:.*]] = catchpad within %[[CATCHSWITCHPAD]] [%rtti.TypeDescriptor2* @"??_R0N@8", i32 0, i8* null]
+// CHECK: call i32 @"?f@@YAHH@Z"(i32 3)
+// CHECK: catchret from %[[CATCHPAD_DOUBLE]] to label %[[LEAVE_DOUBLE_CATCH:.*]]
+
+// CHECK: [[LEAVE_DOUBLE_CATCH]]
+// CHECK: br label %[[LEAVE_FUNC]]
+
+// CHECK: [[NORMAL]]
+// CHECK: br label %[[LEAVE_FUNC]]
+
+struct Cleanup {
+ ~Cleanup() { f(-1); }
+};
+
+void test_cleanup() {
+ Cleanup C;
+ f(1);
+}
+
+// CHECK-LABEL: define dso_local {{.*}} @"?test_cleanup@@YAXXZ"(
+// CHECK: invoke i32 @"?f@@YAHH@Z"(i32 1)
+// CHECK: to label %[[LEAVE_FUNC:.*]] unwind label %[[CLEANUP:.*]]
+
+// CHECK: [[LEAVE_FUNC]]
+// CHECK: call x86_thiscallcc void @"??1Cleanup@@QAE@XZ"(
+// CHECK: ret void
+
+// CHECK: [[CLEANUP]]
+// CHECK: %[[CLEANUPPAD:.*]] = cleanuppad within none []
+// CHECK: call x86_thiscallcc void @"??1Cleanup@@QAE@XZ"(
+// CHECK: cleanupret from %[[CLEANUPPAD]] unwind to caller
+
+
+// CHECK-LABEL: define {{.*}} void @"??1Cleanup@@QAE@XZ"(
+// CHECK: invoke i32 @"?f@@YAHH@Z"(i32 -1)
+// CHECK: to label %[[LEAVE_FUNC:.*]] unwind label %[[TERMINATE:.*]]
+
+// CHECK: [[LEAVE_FUNC]]
+// CHECK: ret void
+
+// CHECK: [[TERMINATE]]
+// CHECK: %[[CLEANUPPAD:.*]] = cleanuppad within none []
+// CHECK-NEXT: call void @"?terminate@@YAXXZ"() {{.*}} [ "funclet"(token %[[CLEANUPPAD]]) ]
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/exceptions-no-rtti.cpp b/src/llvm-project/clang/test/CodeGenCXX/exceptions-no-rtti.cpp
new file mode 100644
index 0000000..e1ef4f1
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/exceptions-no-rtti.cpp
@@ -0,0 +1,51 @@
+// RUN: %clang_cc1 -fno-rtti -fcxx-exceptions -fexceptions %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+// CHECK: @_ZTIN5test11AE = linkonce_odr constant
+// CHECK: @_ZTIN5test11BE = linkonce_odr constant
+// CHECK: @_ZTIN5test11CE = linkonce_odr constant
+// CHECK: @_ZTIN5test11DE = linkonce_odr constant
+// CHECK: @_ZTIPN5test11DE = linkonce_odr constant {{.*}} @_ZTIN5test11DE
+
+// PR6974: this shouldn't crash
+namespace test0 {
+ class err {};
+
+ void f(void) {
+ try {
+ } catch (err &) {
+ }
+ }
+}
+
+namespace test1 {
+ // These classes have key functions defined out-of-line. Under
+ // normal circumstances, we wouldn't generate RTTI for them; under
+ // -fno-rtti, we generate RTTI only when required by EH. But
+ // everything gets hidden visibility because we assume that all
+ // users are also compiled under -fno-rtti and therefore will be
+ // emitting RTTI regardless of key function.
+ class A { virtual void foo(); };
+ class B { virtual void foo(); };
+ class C { virtual void foo(); };
+ class D { virtual void foo(); };
+
+ void opaque();
+
+ void test0() {
+ throw A();
+ }
+
+ void test1() throw(B) {
+ opaque();
+ }
+
+ void test2() {
+ try {
+ opaque();
+ } catch (C&) {}
+ }
+
+ void test3(D *ptr) {
+ throw ptr;
+ };
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/exceptions-seh-filter-captures.cpp b/src/llvm-project/clang/test/CodeGenCXX/exceptions-seh-filter-captures.cpp
new file mode 100644
index 0000000..79fba75
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/exceptions-seh-filter-captures.cpp
@@ -0,0 +1,83 @@
+// RUN: %clang_cc1 -std=c++11 -fblocks -fms-extensions %s -triple=x86_64-windows-msvc -emit-llvm \
+// RUN: -o - -mconstructor-aliases -fcxx-exceptions -fexceptions | \
+// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CXXEH
+
+extern "C" int basic_filter(int v, ...);
+extern "C" void might_crash();
+
+extern "C" void test_freefunc(int p1) {
+ int l1 = 13;
+ static int s1 = 42;
+ __try {
+ might_crash();
+ } __except(basic_filter(p1, l1, s1)) {
+ }
+}
+
+// CHECK-LABEL: define dso_local void @test_freefunc(i32 %p1)
+// CHECK: @llvm.localescape(i32* %[[p1_ptr:[^, ]*]], i32* %[[l1_ptr:[^, ]*]])
+// CHECK: store i32 %p1, i32* %[[p1_ptr]], align 4
+// CHECK: store i32 13, i32* %[[l1_ptr]], align 4
+// CHECK: invoke void @might_crash()
+
+// CHECK-LABEL: define internal i32 @"?filt$0@0@test_freefunc@@"(i8* %exception_pointers, i8* %frame_pointer)
+// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.eh.recoverfp(i8* bitcast (void (i32)* @test_freefunc to i8*), i8* %frame_pointer)
+// CHECK: %[[p1_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (i32)* @test_freefunc to i8*), i8* %[[fp]], i32 0)
+// CHECK: %[[p1_ptr:[^ ]*]] = bitcast i8* %[[p1_i8]] to i32*
+// CHECK: %[[l1_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (i32)* @test_freefunc to i8*), i8* %[[fp]], i32 1)
+// CHECK: %[[l1_ptr:[^ ]*]] = bitcast i8* %[[l1_i8]] to i32*
+// CHECK: %[[s1:[^ ]*]] = load i32, i32* @"?s1@?1??test_freefunc@@9@4HA", align 4
+// CHECK: %[[l1:[^ ]*]] = load i32, i32* %[[l1_ptr]]
+// CHECK: %[[p1:[^ ]*]] = load i32, i32* %[[p1_ptr]]
+// CHECK: call i32 (i32, ...) @basic_filter(i32 %[[p1]], i32 %[[l1]], i32 %[[s1]])
+
+struct S {
+ int m1;
+ void test_method(void);
+};
+
+void S::test_method() {
+ int l1 = 13;
+ __try {
+ might_crash();
+ } __except(basic_filter(l1)) {
+ // FIXME: Test capturing 'this' and 'm1'.
+ }
+}
+
+// CHECK-LABEL: define dso_local void @"?test_method@S@@QEAAXXZ"(%struct.S* %this)
+// CHECK: @llvm.localescape(i32* %[[l1_addr:[^, ]*]])
+// CHECK: store i32 13, i32* %[[l1_addr]], align 4
+// CHECK: invoke void @might_crash()
+
+// CHECK-LABEL: define internal i32 @"?filt$0@0@test_method@S@@"(i8* %exception_pointers, i8* %frame_pointer)
+// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.eh.recoverfp(i8* bitcast (void (%struct.S*)* @"?test_method@S@@QEAAXXZ" to i8*), i8* %frame_pointer)
+// CHECK: %[[l1_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (%struct.S*)* @"?test_method@S@@QEAAXXZ" to i8*), i8* %[[fp]], i32 0)
+// CHECK: %[[l1_ptr:[^ ]*]] = bitcast i8* %[[l1_i8]] to i32*
+// CHECK: %[[l1:[^ ]*]] = load i32, i32* %[[l1_ptr]]
+// CHECK: call i32 (i32, ...) @basic_filter(i32 %[[l1]])
+
+void test_lambda() {
+ int l1 = 13;
+ auto lambda = [&]() {
+ int l2 = 42;
+ __try {
+ might_crash();
+ } __except(basic_filter(l2)) {
+ // FIXME: Test 'l1' when we can capture the lambda's 'this' decl.
+ }
+ };
+ lambda();
+}
+
+// CHECK-LABEL: define internal void @"??R<lambda_0>@?0??test_lambda@@YAXXZ@QEBA@XZ"(%class.anon* %this)
+// CHECK: @llvm.localescape(i32* %[[l2_addr:[^, ]*]])
+// CHECK: store i32 42, i32* %[[l2_addr]], align 4
+// CHECK: invoke void @might_crash()
+
+// CHECK-LABEL: define internal i32 @"?filt$0@0@?R<lambda_0>@?0??test_lambda@@YAXXZ@"(i8* %exception_pointers, i8* %frame_pointer)
+// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.eh.recoverfp(i8* bitcast (void (%class.anon*)* @"??R<lambda_0>@?0??test_lambda@@YAXXZ@QEBA@XZ" to i8*), i8* %frame_pointer)
+// CHECK: %[[l2_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (%class.anon*)* @"??R<lambda_0>@?0??test_lambda@@YAXXZ@QEBA@XZ" to i8*), i8* %[[fp]], i32 0)
+// CHECK: %[[l2_ptr:[^ ]*]] = bitcast i8* %[[l2_i8]] to i32*
+// CHECK: %[[l2:[^ ]*]] = load i32, i32* %[[l2_ptr]]
+// CHECK: call i32 (i32, ...) @basic_filter(i32 %[[l2]])
diff --git a/src/llvm-project/clang/test/CodeGenCXX/exceptions-seh.cpp b/src/llvm-project/clang/test/CodeGenCXX/exceptions-seh.cpp
new file mode 100644
index 0000000..5f88a7b
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/exceptions-seh.cpp
@@ -0,0 +1,166 @@
+// RUN: %clang_cc1 -std=c++11 -fblocks -fms-extensions %s -triple=x86_64-windows-msvc -emit-llvm \
+// RUN: -o - -mconstructor-aliases -fcxx-exceptions -fexceptions | \
+// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CXXEH
+// RUN: %clang_cc1 -std=c++11 -fblocks -fms-extensions %s -triple=x86_64-windows-msvc -emit-llvm \
+// RUN: -o - -mconstructor-aliases -O1 -disable-llvm-passes | \
+// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=NOCXX
+
+extern "C" unsigned long _exception_code();
+extern "C" void might_throw();
+
+struct HasCleanup {
+ HasCleanup();
+ ~HasCleanup();
+ int padding;
+};
+
+extern "C" void use_cxx() {
+ HasCleanup x;
+ might_throw();
+}
+
+// Make sure we use __CxxFrameHandler3 for C++ EH.
+
+// CXXEH-LABEL: define dso_local void @use_cxx()
+// CXXEH-SAME: personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
+// CXXEH: call %struct.HasCleanup* @"??0HasCleanup@@QEAA@XZ"(%struct.HasCleanup* %{{.*}})
+// CXXEH: invoke void @might_throw()
+// CXXEH: to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]
+//
+// CXXEH: [[cont]]
+// CXXEH: call void @"??1HasCleanup@@QEAA@XZ"(%struct.HasCleanup* %{{.*}})
+// CXXEH: ret void
+//
+// CXXEH: [[lpad]]
+// CXXEH: cleanuppad
+// CXXEH: call void @"??1HasCleanup@@QEAA@XZ"(%struct.HasCleanup* %{{.*}})
+// CXXEH: cleanupret
+
+// NOCXX-LABEL: define dso_local void @use_cxx()
+// NOCXX-NOT: invoke
+// NOCXX: call %struct.HasCleanup* @"??0HasCleanup@@QEAA@XZ"(%struct.HasCleanup* %{{.*}})
+// NOCXX-NOT: invoke
+// NOCXX: call void @might_throw()
+// NOCXX-NOT: invoke
+// NOCXX: call void @"??1HasCleanup@@QEAA@XZ"(%struct.HasCleanup* %{{.*}})
+// NOCXX-NOT: invoke
+// NOCXX: ret void
+
+extern "C" void use_seh() {
+ __try {
+ might_throw();
+ } __except(1) {
+ }
+}
+
+// Make sure we use __C_specific_handler for SEH.
+
+// CHECK-LABEL: define dso_local void @use_seh()
+// CHECK-SAME: personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
+// CHECK: invoke void @might_throw() #[[NOINLINE:[0-9]+]]
+// CHECK: to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]
+//
+// CHECK: [[lpad]]
+// CHECK-NEXT: %[[switch:.*]] = catchswitch within none [label %[[cpad:.*]]] unwind to caller
+//
+// CHECK: [[cpad]]
+// CHECK-NEXT: catchpad within %[[switch]]
+// CHECK: catchret {{.*}} label %[[except:[^ ]*]]
+//
+// CHECK: [[except]]
+// CHECK: br label %[[ret:[^ ]*]]
+//
+// CHECK: [[ret]]
+// CHECK: ret void
+//
+// CHECK: [[cont]]
+// CHECK: br label %[[ret]]
+
+extern "C" void nested_finally() {
+ __try {
+ might_throw();
+ } __finally {
+ __try {
+ might_throw();
+ } __finally {
+ }
+ }
+}
+
+// CHECK-LABEL: define dso_local void @nested_finally() #{{[0-9]+}}
+// CHECK-SAME: personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
+// CHECK: invoke void @might_throw()
+// CHECK: call void @"?fin$0@0@nested_finally@@"(i8 1, i8* {{.*}})
+
+// CHECK-LABEL: define internal void @"?fin$0@0@nested_finally@@"
+// CHECK-SAME: personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
+// CHECK: invoke void @might_throw()
+// CHECK: call void @"?fin$1@0@nested_finally@@"(i8 1, i8* {{.*}})
+
+void use_seh_in_lambda() {
+ ([]() {
+ __try {
+ might_throw();
+ } __except(1) {
+ }
+ })();
+ HasCleanup x;
+ might_throw();
+}
+
+// CXXEH-LABEL: define dso_local void @"?use_seh_in_lambda@@YAXXZ"()
+// CXXEH-SAME: personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
+// CXXEH: cleanuppad
+
+// NOCXX-LABEL: define dso_local void @"?use_seh_in_lambda@@YAXXZ"()
+// NOCXX-NOT: invoke
+// NOCXX: ret void
+
+// CHECK-LABEL: define internal void @"??R<lambda_0>@?0??use_seh_in_lambda@@YAXXZ@QEBA@XZ"(%class.anon* %this)
+// CXXEH-SAME: personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
+// CHECK: invoke void @might_throw() #[[NOINLINE]]
+// CHECK: catchpad
+
+static int my_unique_global;
+
+extern "C" inline void use_seh_in_inline_func() {
+ __try {
+ might_throw();
+ } __except(_exception_code() == 424242) {
+ }
+ __try {
+ might_throw();
+ } __finally {
+ my_unique_global = 1234;
+ }
+}
+
+void use_inline() {
+ use_seh_in_inline_func();
+}
+
+// CHECK-LABEL: define linkonce_odr dso_local void @use_seh_in_inline_func() #{{[0-9]+}}
+// CHECK-SAME: personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
+// CHECK: invoke void @might_throw()
+//
+// CHECK: catchpad {{.*}} [i8* bitcast (i32 (i8*, i8*)* @"?filt$0@0@use_seh_in_inline_func@@" to i8*)]
+//
+// CHECK: invoke void @might_throw()
+//
+// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
+// CHECK: call void @"?fin$0@0@use_seh_in_inline_func@@"(i8 0, i8* %[[fp]])
+// CHECK: ret void
+//
+// CHECK: cleanuppad
+// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
+// CHECK: call void @"?fin$0@0@use_seh_in_inline_func@@"(i8 1, i8* %[[fp]])
+
+// CHECK-LABEL: define internal i32 @"?filt$0@0@use_seh_in_inline_func@@"(i8* %exception_pointers, i8* %frame_pointer) #{{[0-9]+}}
+// CHECK: icmp eq i32 %{{.*}}, 424242
+// CHECK: zext i1 %{{.*}} to i32
+// CHECK: ret i32
+
+// CHECK-LABEL: define internal void @"?fin$0@0@use_seh_in_inline_func@@"(i8 %abnormal_termination, i8* %frame_pointer) #{{[0-9]+}}
+// CHECK: store i32 1234, i32* @my_unique_global
+
+// CHECK: attributes #[[NOINLINE]] = { {{.*noinline.*}} }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/exceptions.cpp b/src/llvm-project/clang/test/CodeGenCXX/exceptions.cpp
new file mode 100644
index 0000000..e31d6fc
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/exceptions.cpp
@@ -0,0 +1,597 @@
+// RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -emit-llvm -std=c++98 -o - -fcxx-exceptions -fexceptions | FileCheck -check-prefix=CHECK -check-prefix=CHECK98 %s
+// RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -emit-llvm -std=c++11 -o - -fcxx-exceptions -fexceptions | FileCheck -check-prefix=CHECK -check-prefix=CHECK11 %s
+
+typedef __typeof(sizeof(0)) size_t;
+
+// Declare the reserved global placement new.
+void *operator new(size_t, void*);
+
+// This just shouldn't crash.
+namespace test0 {
+ struct allocator {
+ allocator();
+ allocator(const allocator&);
+ ~allocator();
+ };
+
+ 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 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 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: [[NEW:%.*]] = call i8* @_Znwm(i64 8)
+ // CHECK-NEXT: store i1 true, i1* [[ACTIVE]]
+ // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
+ // CHECK-NEXT: invoke void @_ZN5test11BC1Ev([[B:%.*]]* [[T0:%.*]])
+ // CHECK: [[T1:%.*]] = getelementptr inbounds [[B]], [[B]]* [[T0]], i32 0, i32 0
+ // CHECK-NEXT: [[T2:%.*]] = load i32, i32* [[T1]], align 4
+ // CHECK-NEXT: invoke void @_ZN5test11AC1Ei([[A]]* [[CAST]], i32 [[T2]])
+ // CHECK: store i1 false, i1* [[ACTIVE]]
+
+ // CHECK98-NEXT: invoke void @_ZN5test11BD1Ev([[B]]* [[T0]])
+ // CHECK11-NEXT: call void @_ZN5test11BD1Ev([[B]]* [[T0]])
+
+ // CHECK: ret [[A]]* [[CAST]]
+ // CHECK: [[ISACTIVE:%.*]] = load i1, i1* [[ACTIVE]]
+ // CHECK-NEXT: br i1 [[ISACTIVE]]
+ // CHECK: call void @_ZdlPv(i8* [[NEW]])
+ return new A(B().x);
+ }
+
+ // rdar://11904428
+ // Terminate landing pads should call __cxa_begin_catch first.
+ // CHECK98: define linkonce_odr hidden void @__clang_call_terminate(i8*) [[NI_NR_NUW:#[0-9]+]] comdat
+ // CHECK98-NEXT: [[T0:%.*]] = call i8* @__cxa_begin_catch(i8* %0) [[NUW:#[0-9]+]]
+ // CHECK98-NEXT: call void @_ZSt9terminatev() [[NR_NUW:#[0-9]+]]
+ // CHECK98-NEXT: unreachable
+
+ A *d() {
+ // CHECK: define [[A:%.*]]* @_ZN5test11dEv()
+ // CHECK: [[ACTIVE:%.*]] = alloca i1
+ // CHECK-NEXT: [[NEW:%.*]] = call i8* @_Znwm(i64 8)
+ // CHECK-NEXT: store i1 true, i1* [[ACTIVE]]
+ // 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]]
+
+ // CHECK98-NEXT: invoke void @_ZN5test11BD1Ev([[B]]* [[T0]])
+ // CHECK11-NEXT: call void @_ZN5test11BD1Ev([[B]]* [[T0]])
+
+ // CHECK: ret [[A]]* [[CAST]]
+ // CHECK: [[ISACTIVE:%.*]] = load i1, 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: [[NEW:%.*]] = call i8* @_Znwm(i64 8)
+ // CHECK-NEXT: store i1 true, i1* [[ACTIVE]]
+ // 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]]
+
+ // CHECK98-NEXT: invoke void @_ZN5test11BD1Ev([[B]]* [[T2]])
+ // CHECK11-NEXT: call void @_ZN5test11BD1Ev([[B]]* [[T2]])
+
+ // CHECK98: invoke void @_ZN5test11BD1Ev([[B]]* [[T0]])
+ // CHECK11: call void @_ZN5test11BD1Ev([[B]]* [[T0]])
+
+ // CHECK: ret [[A]]* [[CAST]]
+ // CHECK: [[ISACTIVE:%.*]] = load i1, 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: [[NEW:%.*]] = call i8* @_Znwm(i64 8)
+ // CHECK-NEXT: store i1 true, i1* [[ACTIVE]]
+ // 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]]*, [[A]]** [[X]], align 8
+
+ // CHECK98: invoke void @_ZN5test11BD1Ev([[B]]* [[T2]])
+ // CHECK11: call void @_ZN5test11BD1Ev([[B]]* [[T2]])
+
+ // CHECK98: invoke void @_ZN5test11BD1Ev([[B]]* [[T0]])
+ // CHECK11: call void @_ZN5test11BD1Ev([[B]]* [[T0]])
+
+ // CHECK: ret [[A]]* [[RET]]
+ // CHECK: [[ISACTIVE:%.*]] = load i1, 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]]
+
+ // CHECK98: invoke void @_ZN5test21AdlEPvm(i8* [[NEW]], i64 8)
+ // CHECK11: call void @_ZN5test21AdlEPvm(i8* [[NEW]], i64 8)
+
+ // CHECK98: call void @__clang_call_terminate(i8* {{%.*}}) [[NR_NUW]]
+ 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]]
+
+ // CHECK98: invoke void @_ZN5test31AdlEPvS1_d(i8* [[NEW]], i8* [[FOO]], double [[BAR]])
+ // CHECK11: call void @_ZN5test31AdlEPvS1_d(i8* [[NEW]], i8* [[FOO]], double [[BAR]])
+
+ // CHECK98: call void @__clang_call_terminate(i8* {{%.*}}) [[NR_NUW]]
+ 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: [[COND:%.*]] = trunc i8 {{.*}} to i1
+ // CHECK-NEXT: store i1 false, i1* [[CLEANUPACTIVE]]
+ // 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 [[CAST]])
+ // CHECK: br label
+ // -> cond.end
+ new(foo(),10.0) A(makeA()) :
+
+ // CHECK: [[MAKE:%.*]] = call [[A]]* @_ZN5test38makeAPtrEv()
+ // CHECK: br label
+ // -> cond.end
+ makeAPtr());
+
+ // cond.end:
+ // CHECK: [[RESULT:%.*]] = phi [[A]]* {{.*}}[[CAST]]{{.*}}[[MAKE]]
+ // CHECK: ret [[A]]* [[RESULT]]
+
+ // in the EH path:
+ // CHECK: [[ISACTIVE:%.*]] = load i1, i1* [[CLEANUPACTIVE]]
+ // CHECK-NEXT: br i1 [[ISACTIVE]]
+ // CHECK: [[V0:%.*]] = load i8*, i8** [[SAVED0]]
+ // CHECK-NEXT: [[V1:%.*]] = load i8*, i8** [[SAVED1]]
+
+ // CHECK98-NEXT: invoke void @_ZN5test31AdlEPvS1_d(i8* [[V0]], i8* [[V1]], double [[CONST]])
+ // CHECK11-NEXT: call 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-LABEL: define void @_ZN5test54testEv()
+ // CHECK: [[EXNSLOT:%.*]] = alloca i8*
+ // CHECK-NEXT: [[SELECTORSLOT:%.*]] = alloca i32
+ // CHECK-NEXT: [[A:%.*]] = alloca [[A_T:%.*]], align 1
+ // CHECK-NEXT: [[T:%.*]] = alloca [[T_T:%.*]], align 1
+ // CHECK-NEXT: invoke void @_ZN5test53fooEv()
+ // CHECK: [[EXN:%.*]] = load i8*, 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]]* dereferenceable({{[0-9]+}}) [[SRC]], [[T_T]]* dereferenceable({{[0-9]+}}) [[T]])
+
+ // CHECK98: invoke void @_ZN5test51TD1Ev([[T_T]]* [[T]])
+ // CHECK11: call void @_ZN5test51TD1Ev([[T_T]]* [[T]])
+
+ // CHECK98: call i8* @__cxa_begin_catch(i8* [[EXN]]) [[NUW]]
+ // CHECK98-NEXT: invoke void @_ZN5test51AD1Ev([[A_T]]* [[A]])
+
+ // CHECK: call void @__cxa_end_catch()
+ void test() {
+ try {
+ foo();
+ } catch (A a) {
+ }
+ }
+}
+
+// PR9303: invalid assert on this
+namespace test6 {
+ bool cond();
+ void test() {
+ try {
+ lbl:
+ if (cond()) goto lbl;
+ } catch (...) {
+ }
+ }
+}
+
+// PR9298
+namespace test7 {
+ struct A { A(); ~A(); };
+ struct B {
+ // The throw() operator means that a bad allocation is signalled
+ // with a null return, which means that the initializer is
+ // evaluated conditionally.
+ static void *operator new(size_t size) throw();
+ B(const A&, B*);
+ ~B();
+ };
+
+ B *test() {
+ // CHECK: define [[B:%.*]]* @_ZN5test74testEv()
+ // CHECK: [[OUTER_NEW:%.*]] = alloca i1
+ // CHECK-NEXT: alloca [[A:%.*]],
+ // CHECK-NEXT: alloca i8*
+ // CHECK-NEXT: alloca i32
+ // CHECK-NEXT: [[OUTER_A:%.*]] = alloca i1
+ // CHECK-NEXT: alloca i8*
+ // CHECK-NEXT: [[INNER_NEW:%.*]] = alloca i1
+ // CHECK-NEXT: alloca [[A]]
+ // CHECK-NEXT: [[INNER_A:%.*]] = alloca i1
+
+ // Allocate the outer object.
+ // CHECK-NEXT: [[NEW:%.*]] = call i8* @_ZN5test71BnwEm(
+ // CHECK-NEXT: icmp eq i8* [[NEW]], null
+
+ // These stores, emitted before the outermost conditional branch,
+ // deactivate the temporary cleanups.
+ // CHECK-NEXT: store i1 false, i1* [[OUTER_NEW]]
+ // CHECK-NEXT: store i1 false, i1* [[OUTER_A]]
+ // CHECK-NEXT: store i1 false, i1* [[INNER_NEW]]
+ // CHECK-NEXT: store i1 false, i1* [[INNER_A]]
+ // CHECK-NEXT: br i1
+
+ // We passed the first null check; activate that cleanup and continue.
+ // CHECK: store i1 true, i1* [[OUTER_NEW]]
+ // CHECK-NEXT: bitcast
+
+ // Create the first A temporary and activate that cleanup.
+ // CHECK-NEXT: invoke void @_ZN5test71AC1Ev(
+ // CHECK: store i1 true, i1* [[OUTER_A]]
+
+ // Allocate the inner object.
+ // CHECK-NEXT: [[NEW:%.*]] = call i8* @_ZN5test71BnwEm(
+ // CHECK-NEXT: icmp eq i8* [[NEW]], null
+ // CHECK-NEXT: br i1
+
+ // We passed the second null check; save that pointer, activate
+ // that cleanup, and continue.
+ // CHECK: store i8* [[NEW]]
+ // CHECK-NEXT: store i1 true, i1* [[INNER_NEW]]
+ // CHECK-NEXT: bitcast
+
+ // Build the second A temporary and activate that cleanup.
+ // CHECK-NEXT: invoke void @_ZN5test71AC1Ev(
+ // CHECK: store i1 true, i1* [[INNER_A]]
+
+ // Build the inner B object and deactivate the inner delete cleanup.
+ // CHECK-NEXT: invoke void @_ZN5test71BC1ERKNS_1AEPS0_(
+ // CHECK: store i1 false, i1* [[INNER_NEW]]
+ // CHECK: phi
+
+ // Build the outer B object and deactivate the outer delete cleanup.
+ // CHECK-NEXT: invoke void @_ZN5test71BC1ERKNS_1AEPS0_(
+ // CHECK: store i1 false, i1* [[OUTER_NEW]]
+ // CHECK: phi
+ // CHECK-NEXT: store [[B]]*
+
+ // Destroy the inner A object.
+ // CHECK-NEXT: load i1, i1* [[INNER_A]]
+ // CHECK-NEXT: br i1
+
+ // CHECK98: invoke void @_ZN5test71AD1Ev(
+ // CHECK11: call void @_ZN5test71AD1Ev(
+
+ // Destroy the outer A object.
+ // CHECK: load i1, i1* [[OUTER_A]]
+ // CHECK-NEXT: br i1
+
+ // CHECK98: invoke void @_ZN5test71AD1Ev(
+ // CHECK11: call void @_ZN5test71AD1Ev(
+
+ return new B(A(), new B(A(), 0));
+ }
+}
+
+// Just don't crash.
+namespace test8 {
+ struct A {
+ // Having both of these is required to trigger the assert we're
+ // trying to avoid.
+ A(const A&);
+ A&operator=(const A&);
+
+ ~A();
+ };
+
+ A makeA();
+ void test() {
+ throw makeA();
+ }
+ // CHECK-LABEL: define void @_ZN5test84testEv
+}
+
+// Make sure we generate the correct code for the delete[] call which
+// happens if A::A() throws. (We were previously calling delete[] on
+// a pointer to the first array element, not the pointer returned by new[].)
+// PR10870
+namespace test9 {
+ struct A {
+ A();
+ ~A();
+ };
+ A* test() {
+ return new A[10];
+ }
+ // CHECK: define {{%.*}}* @_ZN5test94testEv
+ // CHECK: [[TEST9_NEW:%.*]] = call i8* @_Znam
+ // CHECK: call void @_ZdaPv(i8* [[TEST9_NEW]])
+}
+
+// In a destructor with a function-try-block, a return statement in a
+// catch handler behaves differently from running off the end of the
+// catch handler. PR13102.
+namespace test10 {
+ extern void cleanup();
+ extern bool suppress;
+
+ struct A { ~A(); };
+ A::~A() try { cleanup(); } catch (...) { return; }
+ // CHECK-LABEL: define void @_ZN6test101AD1Ev(
+ // CHECK: invoke void @_ZN6test107cleanupEv()
+ // CHECK-NOT: rethrow
+ // CHECK: ret void
+
+ struct B { ~B(); };
+ B::~B() try { cleanup(); } catch (...) {}
+ // CHECK-LABEL: define void @_ZN6test101BD1Ev(
+ // CHECK: invoke void @_ZN6test107cleanupEv()
+ // CHECK: call i8* @__cxa_begin_catch
+ // CHECK-NEXT: invoke void @__cxa_rethrow()
+ // CHECK: unreachable
+
+ struct C { ~C(); };
+ C::~C() try { cleanup(); } catch (...) { if (suppress) return; }
+ // CHECK-LABEL: define void @_ZN6test101CD1Ev(
+ // CHECK: invoke void @_ZN6test107cleanupEv()
+ // CHECK: call i8* @__cxa_begin_catch
+ // CHECK-NEXT: load i8, i8* @_ZN6test108suppressE, align 1
+ // CHECK-NEXT: trunc
+ // CHECK-NEXT: br i1
+
+ // CHECK98: call void @__cxa_end_catch()
+ // CHECK98-NEXT: br label
+ // CHECK11: invoke void @__cxa_end_catch()
+ // CHECK11-NEXT: to label
+
+ // CHECK: invoke void @__cxa_rethrow()
+ // CHECK: unreachable
+}
+
+// Ensure that an exception in a constructor destroys
+// already-constructed array members. PR14514
+namespace test11 {
+ struct A {
+ A();
+ ~A() {}
+ };
+
+ struct C {
+ A single;
+ A array[2][3];
+
+ C();
+ };
+
+ C::C() {
+ throw 0;
+ }
+ // CHECK-LABEL: define void @_ZN6test111CC2Ev(
+ // CHECK: [[THIS:%.*]] = load [[C:%.*]]*, [[C:%.*]]** {{%.*}}
+ // Construct single.
+ // CHECK-NEXT: [[SINGLE:%.*]] = getelementptr inbounds [[C]], [[C]]* [[THIS]], i32 0, i32 0
+ // CHECK-NEXT: call void @_ZN6test111AC1Ev([[A:%.*]]* [[SINGLE]])
+ // Construct array.
+ // CHECK-NEXT: [[ARRAY:%.*]] = getelementptr inbounds [[C]], [[C]]* [[THIS]], i32 0, i32 1
+ // CHECK-NEXT: [[ARRAYBEGIN:%.*]] = getelementptr inbounds [2 x [3 x [[A]]]], [2 x [3 x [[A]]]]* [[ARRAY]], i32 0, i32 0, i32 0
+ // CHECK-NEXT: [[ARRAYEND:%.*]] = getelementptr inbounds [[A]], [[A]]* [[ARRAYBEGIN]], i64 6
+ // CHECK-NEXT: br label
+ // CHECK: [[CUR:%.*]] = phi [[A]]* [ [[ARRAYBEGIN]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ]
+ // CHECK-NEXT: invoke void @_ZN6test111AC1Ev([[A:%.*]]* [[CUR]])
+ // CHECK: [[NEXT]] = getelementptr inbounds [[A]], [[A]]* [[CUR]], i64 1
+ // CHECK-NEXT: [[DONE:%.*]] = icmp eq [[A]]* [[NEXT]], [[ARRAYEND]]
+ // CHECK-NEXT: br i1 [[DONE]],
+ // throw 0;
+ // CHECK: invoke void @__cxa_throw(
+ // Landing pad 1, from constructor in array-initialization loop:
+ // CHECK: landingpad
+ // - First, destroy already-constructed bits of array.
+ // CHECK: [[EMPTY:%.*]] = icmp eq [[A]]* [[ARRAYBEGIN]], [[CUR]]
+ // CHECK-NEXT: br i1 [[EMPTY]]
+ // CHECK: [[AFTER:%.*]] = phi [[A]]* [ [[CUR]], {{%.*}} ], [ [[ELT:%.*]], {{%.*}} ]
+ // CHECK-NEXT: [[ELT]] = getelementptr inbounds [[A]], [[A]]* [[AFTER]], i64 -1
+
+ // CHECK98-NEXT: invoke void @_ZN6test111AD1Ev([[A]]* [[ELT]])
+ // CHECK11-NEXT: call void @_ZN6test111AD1Ev([[A]]* [[ELT]])
+
+ // CHECK: [[DONE:%.*]] = icmp eq [[A]]* [[ELT]], [[ARRAYBEGIN]]
+ // CHECK-NEXT: br i1 [[DONE]],
+ // - Next, chain to cleanup for single.
+ // CHECK: br label
+ // Landing pad 2, from throw site.
+ // CHECK: landingpad
+ // - First, destroy all of array.
+ // CHECK: [[ARRAYBEGIN:%.*]] = getelementptr inbounds [2 x [3 x [[A]]]], [2 x [3 x [[A]]]]* [[ARRAY]], i32 0, i32 0, i32 0
+ // CHECK-NEXT: [[ARRAYEND:%.*]] = getelementptr inbounds [[A]], [[A]]* [[ARRAYBEGIN]], i64 6
+ // CHECK-NEXT: br label
+ // CHECK: [[AFTER:%.*]] = phi [[A]]* [ [[ARRAYEND]], {{%.*}} ], [ [[ELT:%.*]], {{%.*}} ]
+ // CHECK-NEXT: [[ELT]] = getelementptr inbounds [[A]], [[A]]* [[AFTER]], i64 -1
+
+ // CHECK98-NEXT: invoke void @_ZN6test111AD1Ev([[A]]* [[ELT]])
+ // CHECK11-NEXT: call void @_ZN6test111AD1Ev([[A]]* [[ELT]])
+
+ // CHECK: [[DONE:%.*]] = icmp eq [[A]]* [[ELT]], [[ARRAYBEGIN]]
+ // CHECK-NEXT: br i1 [[DONE]],
+ // - Next, chain to cleanup for single.
+ // CHECK: br label
+ // Finally, the cleanup for single.
+
+ // CHECK98: invoke void @_ZN6test111AD1Ev([[A]]* [[SINGLE]])
+ // CHECK11: call void @_ZN6test111AD1Ev([[A]]* [[SINGLE]])
+
+ // CHECK: br label
+ // CHECK: resume
+ // (After this is a terminate landingpad.)
+}
+
+namespace test12 {
+ struct A {
+ void operator delete(void *, void *);
+ A();
+ };
+
+ A *test(void *ptr) {
+ return new (ptr) A();
+ }
+ // CHECK-LABEL: define {{.*}} @_ZN6test124testEPv(
+ // CHECK: [[PTR:%.*]] = load i8*, i8*
+ // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[PTR]] to [[A:%.*]]*
+ // CHECK-NEXT: invoke void @_ZN6test121AC1Ev([[A]]* [[CAST]])
+ // CHECK: ret [[A]]* [[CAST]]
+
+ // CHECK98: invoke void @_ZN6test121AdlEPvS1_(i8* [[PTR]], i8* [[PTR]])
+ // CHECK11: call void @_ZN6test121AdlEPvS1_(i8* [[PTR]], i8* [[PTR]])
+}
+
+// CHECK98: attributes [[NI_NR_NUW]] = { noinline noreturn nounwind }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/explicit-instantiation.cpp b/src/llvm-project/clang/test/CodeGenCXX/explicit-instantiation.cpp
new file mode 100644
index 0000000..07c5f72
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/explicit-instantiation.cpp
@@ -0,0 +1,191 @@
+// RUN: %clang_cc1 -emit-llvm -triple i686-pc-linux-gnu -std=c++1y -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NO-OPT
+// RUN: %clang_cc1 -emit-llvm -triple i686-pc-linux-gnu -std=c++1y -O3 -disable-llvm-passes -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-OPT
+// RUN: %clang_cc1 -emit-llvm -triple i686-pc-win32 -std=c++1y -o - %s | FileCheck %s --check-prefix=CHECK-MS
+
+// This check logically is attached to 'template int S<int>::i;' below.
+// CHECK: @_ZN1SIiE1iE = weak_odr global i32
+
+// This check is logically attached to 'template int ExportedStaticLocal::f<int>()' below.
+// CHECK-OPT: @_ZZN19ExportedStaticLocal1fIiEEvvE1i = linkonce_odr global
+
+template<typename T, typename U, typename Result>
+struct plus {
+ Result operator()(const T& t, const U& u) const;
+};
+
+template<typename T, typename U, typename Result>
+Result plus<T, U, Result>::operator()(const T& t, const U& u) const {
+ return t + u;
+}
+
+// CHECK-LABEL: define weak_odr i32 @_ZNK4plusIillEclERKiRKl
+template struct plus<int, long, long>;
+
+namespace EarlyInstantiation {
+ // Check that we emit definitions if we instantiate a function definition before
+ // it gets explicitly instantiatied.
+ template<typename T> struct S {
+ constexpr int constexpr_function() { return 0; }
+ auto deduced_return_type() { return 0; }
+ };
+
+ // From an implicit instantiation.
+ constexpr int a = S<char>().constexpr_function();
+ int b = S<char>().deduced_return_type();
+
+ // From an explicit instantiation declaration.
+ extern template struct S<int>;
+ constexpr int c = S<int>().constexpr_function();
+ int d = S<int>().deduced_return_type();
+
+ // CHECK: define weak_odr i32 @_ZN18EarlyInstantiation1SIcE18constexpr_functionEv(
+ // CHECK: define weak_odr i32 @_ZN18EarlyInstantiation1SIcE19deduced_return_typeEv(
+ // CHECK: define weak_odr i32 @_ZN18EarlyInstantiation1SIiE18constexpr_functionEv(
+ // CHECK: define weak_odr i32 @_ZN18EarlyInstantiation1SIiE19deduced_return_typeEv(
+ template struct S<char>;
+ template struct S<int>;
+
+ template<typename T> constexpr int constexpr_function() { return 0; }
+ template<typename T> auto deduced_return_type() { return 0; }
+
+ // From an implicit instantiation.
+ constexpr int e = constexpr_function<char>();
+ int f = deduced_return_type<char>();
+
+ // From an explicit instantiation declaration.
+ extern template int constexpr_function<int>();
+ extern template auto deduced_return_type<int>();
+ constexpr int g = constexpr_function<int>();
+ int h = deduced_return_type<int>();
+
+ // The FIXMEs below are for PR19551.
+ // CHECK: define weak_odr i32 @_ZN18EarlyInstantiation18constexpr_functionIcEEiv(
+ // FIXME: define weak_odr i32 @_ZN18EarlyInstantiation19deduced_return_typeIcEEiv(
+ // CHECK: define weak_odr i32 @_ZN18EarlyInstantiation18constexpr_functionIiEEiv(
+ // FIXME: define weak_odr i32 @_ZN18EarlyInstantiation19deduced_return_typeIiEEiv(
+ template int constexpr_function<char>();
+ // FIXME template auto deduced_return_type<char>();
+ template int constexpr_function<int>();
+ // FIXME template auto deduced_return_type<int>();
+}
+
+namespace LateInstantiation {
+ // Check that we downgrade the linkage to available_externally if we see an
+ // explicit instantiation declaration after the function template is
+ // instantiated.
+ template<typename T> struct S { constexpr int f() { return 0; } };
+ template<typename T> constexpr int f() { return 0; }
+
+ // Trigger eager instantiation of the function definitions.
+ int a, b = S<char>().f() + f<char>() + a;
+ int c, d = S<int>().f() + f<int>() + a;
+
+ // Don't allow some of those definitions to be emitted.
+ extern template struct S<int>;
+ extern template int f<int>();
+
+ // Check that we declare, define, or provide an available-externally
+ // definition as appropriate.
+ // CHECK: define linkonce_odr i32 @_ZN17LateInstantiation1SIcE1fEv(
+ // CHECK: define linkonce_odr i32 @_ZN17LateInstantiation1fIcEEiv(
+ // CHECK-NO-OPT: declare i32 @_ZN17LateInstantiation1SIiE1fEv(
+ // CHECK-NO-OPT: declare i32 @_ZN17LateInstantiation1fIiEEiv(
+ // CHECK-OPT: define available_externally i32 @_ZN17LateInstantiation1SIiE1fEv(
+ // CHECK-OPT: define available_externally i32 @_ZN17LateInstantiation1fIiEEiv(
+}
+
+namespace PR21718 {
+// The linkage of a used constexpr member function can change from linkonce_odr
+// to weak_odr after explicit instantiation without errors about defining the
+// same function twice.
+template <typename T>
+struct S {
+// CHECK-LABEL: define weak_odr i32 @_ZN7PR217181SIiE1fEv
+ __attribute__((used)) constexpr int f() { return 0; }
+};
+int g() { return S<int>().f(); }
+template struct S<int>;
+}
+
+namespace NestedClasses {
+ // Check how explicit instantiation of an outer class affects the inner class.
+ template <typename T> struct Outer {
+ struct Inner {
+ void f() {}
+ };
+ };
+
+ // Explicit instantiation definition of Outer causes explicit instantiation
+ // definition of Inner.
+ template struct Outer<int>;
+ // CHECK: define weak_odr void @_ZN13NestedClasses5OuterIiE5Inner1fEv
+ // CHECK-MS: define weak_odr dso_local x86_thiscallcc void @"?f@Inner@?$Outer@H@NestedClasses@@QAEXXZ"
+
+ // Explicit instantiation declaration of Outer causes explicit instantiation
+ // declaration of Inner, but not in MSVC mode.
+ extern template struct Outer<char>;
+ auto use = &Outer<char>::Inner::f;
+ // CHECK: {{declare|define available_externally}} void @_ZN13NestedClasses5OuterIcE5Inner1fEv
+ // CHECK-MS: define linkonce_odr dso_local x86_thiscallcc void @"?f@Inner@?$Outer@D@NestedClasses@@QAEXXZ"
+}
+
+// Check that we emit definitions from explicit instantiations even when they
+// occur prior to the definition itself.
+template <typename T> struct S {
+ void f();
+ static void g();
+ static int i;
+ struct S2 {
+ void h();
+ };
+};
+
+// CHECK-LABEL: define weak_odr void @_ZN1SIiE1fEv
+template void S<int>::f();
+
+// CHECK-LABEL: define weak_odr void @_ZN1SIiE1gEv
+template void S<int>::g();
+
+// See the check line at the top of the file.
+template int S<int>::i;
+
+// CHECK-LABEL: define weak_odr void @_ZN1SIiE2S21hEv
+template void S<int>::S2::h();
+
+template <typename T> void S<T>::f() {}
+template <typename T> void S<T>::g() {}
+template <typename T> int S<T>::i;
+template <typename T> void S<T>::S2::h() {}
+
+namespace ExportedStaticLocal {
+void sink(int&);
+template <typename T>
+inline void f() {
+ static int i;
+ sink(i);
+}
+// See the check line at the top of the file.
+extern template void f<int>();
+void use() {
+ f<int>();
+}
+}
+
+namespace DefaultedMembers {
+ struct B { B(); B(const B&); ~B(); };
+ template<typename T> struct A : B {
+ A() = default;
+ ~A() = default;
+ };
+ extern template struct A<int>;
+
+ // CHECK-LABEL: define {{.*}} @_ZN16DefaultedMembers1AIiEC2Ev
+ // CHECK-LABEL: define {{.*}} @_ZN16DefaultedMembers1AIiED2Ev
+ A<int> ai;
+
+ // CHECK-LABEL: define {{.*}} @_ZN16DefaultedMembers1AIiEC2ERKS1_
+ A<int> ai2(ai);
+
+ // CHECK-NOT: @_ZN16DefaultedMembers1AIcE
+ template struct A<char>;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/expr.cpp b/src/llvm-project/clang/test/CodeGenCXX/expr.cpp
new file mode 100644
index 0000000..33e8e63
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/expr.cpp
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -emit-llvm -x c++ < %s
+
+void test0(int x) {
+ if (x != 0) return;
+}
+
+
+// PR5211
+void test1() {
+ char *xpto;
+ while ( true && xpto[0] );
+}
+
+// PR5514
+int a;
+void test2() { ++a+=10; }
+
+// PR7892
+int test3(const char*);
+int test3g = test3(__PRETTY_FUNCTION__);
+
+
+// PR7889
+struct test4A {
+ int j : 2;
+};
+int test4() {
+ test4A a;
+ (a.j = 2) = 3;
+}
+
+// Incomplete type in conditional operator.
+// Check operations on incomplete types.
+struct s5;
+struct s5 &f5_0(bool cond, struct s5 &a, struct s5 &b) {
+ return cond ? a : b;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/extern-c.cpp b/src/llvm-project/clang/test/CodeGenCXX/extern-c.cpp
new file mode 100644
index 0000000..b80d325
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/extern-c.cpp
@@ -0,0 +1,90 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s
+namespace foo {
+
+// CHECK-NOT: @a = global
+extern "C" int a;
+
+// CHECK-NOT: @_ZN3foo1bE = global
+extern int b;
+
+// CHECK: @_ZN3foo1cE = {{(dso_local )?}}global
+int c = 5;
+
+// CHECK-NOT: @_ZN3foo1dE
+extern "C" struct d;
+
+// CHECK-NOT: should_not_appear
+extern "C++" int should_not_appear;
+
+// CHECK: @_ZN3foo10extern_cxxE = {{(dso_local )?}}global
+extern "C++" int extern_cxx = 0;
+
+}
+
+// CHECK-NOT: @global_a = {{(dso_local )?}}global
+extern "C" int global_a;
+
+// CHECK: @global_b = {{(dso_local )?}}global
+extern "C" int global_b = 0;
+
+// CHECK-NOT: should_not_appear
+extern "C++" int should_not_appear;
+
+// CHECK: @extern_cxx = {{(dso_local )?}}global
+extern "C++" int extern_cxx = 0;
+
+namespace test1 {
+ namespace {
+ struct X {};
+ }
+ extern "C" {
+ // CHECK: @test1_b = {{(dso_local )?}}global
+ X test1_b = X();
+ }
+ void *use = &test1_b;
+ // CHECK: @_ZN5test13useE = {{(dso_local )?}}global
+}
+
+namespace test2 {
+ namespace {
+ struct X {};
+ }
+
+ // CHECK: @test2_b = {{(dso_local )?}}global
+ extern "C" X test2_b;
+ X test2_b;
+}
+
+extern "C" {
+ static int unused_var;
+ static int unused_fn() { return 0; }
+
+ __attribute__((used)) static int internal_var;
+ __attribute__((used)) static int internal_fn() { return 0; }
+
+ __attribute__((used)) static int duplicate_internal_var;
+ __attribute__((used)) static int duplicate_internal_fn() { return 0; }
+
+ namespace N {
+ __attribute__((used)) static int duplicate_internal_var;
+ __attribute__((used)) static int duplicate_internal_fn() { return 0; }
+ }
+
+ // CHECK: @llvm.used = appending global {{.*}} @internal_var {{.*}} @internal_fn
+
+ // CHECK-NOT: @unused
+ // CHECK-NOT: @duplicate_internal
+ // CHECK: @internal_var = internal alias i32, i32* @_ZL12internal_var
+ // CHECK-NOT: @unused
+ // CHECK-NOT: @duplicate_internal
+ // CHECK: @internal_fn = internal alias i32 (), i32 ()* @_ZL11internal_fnv
+ // CHECK-NOT: @unused
+ // CHECK-NOT: @duplicate_internal
+}
+
+namespace PR19411 {
+ struct A { void f(); };
+ extern "C" void A::f() { void g(); g(); }
+ // CHECK-LABEL: @_ZN7PR194111A1fEv(
+ // CHECK: call {{.*}}void @g()
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/extern-section-attribute.cpp b/src/llvm-project/clang/test/CodeGenCXX/extern-section-attribute.cpp
new file mode 100644
index 0000000..fa0227e
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/extern-section-attribute.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-pc-linux-gnu | FileCheck %s
+
+extern int aa __attribute__((section(".sdata")));
+// CHECK-DAG: @aa = external global i32, section ".sdata", align 4
+
+extern int bb __attribute__((section(".sdata"))) = 1;
+// CHECK-DAG: @bb = global i32 1, section ".sdata", align 4
+
+int foo() {
+ return aa + bb;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/fastcall.cpp b/src/llvm-project/clang/test/CodeGenCXX/fastcall.cpp
new file mode 100644
index 0000000..0820324
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/fastcall.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -o - %s | FileCheck %s
+
+void __attribute__((fastcall)) foo1(int &y);
+void bar1(int &y) {
+ // CHECK-LABEL: define void @_Z4bar1Ri
+ // CHECK: call x86_fastcallcc void @_Z4foo1Ri(i32* inreg dereferenceable({{[0-9]+}}) %
+ foo1(y);
+}
+
+struct S1 {
+ int x;
+ S1(const S1 &y);
+};
+
+void __attribute__((fastcall)) foo2(S1 a, int b);
+void bar2(S1 a, int b) {
+ // CHECK-LABEL: define void @_Z4bar22S1i
+ // CHECK: call x86_fastcallcc void @_Z4foo22S1i(%struct.S1* inreg %{{.*}}, i32 inreg %
+ foo2(a, b);
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/field-access-debug-info.cpp b/src/llvm-project/clang/test/CodeGenCXX/field-access-debug-info.cpp
new file mode 100644
index 0000000..38c06f1
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/field-access-debug-info.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang -g -S -emit-llvm %s -o - | FileCheck %s
+
+// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "p"
+// CHECK-SAME: baseType: ![[INT:[0-9]+]]
+// CHECK-SAME: DIFlagPublic
+// CHECK: ![[INT]] = !DIBasicType(name: "int"
+// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "pr"
+// CHECK-NOT: flags:
+// CHECK-SAME: baseType: ![[INT]]
+
+class A {
+public:
+ int p;
+private:
+ int pr;
+};
+
+A a;
diff --git a/src/llvm-project/clang/test/CodeGenCXX/finegrain-bitfield-access.cpp b/src/llvm-project/clang/test/CodeGenCXX/finegrain-bitfield-access.cpp
new file mode 100644
index 0000000..2973f9f
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/finegrain-bitfield-access.cpp
@@ -0,0 +1,162 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -ffine-grained-bitfield-accesses \
+// RUN: -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -ffine-grained-bitfield-accesses \
+// RUN: -emit-llvm -fsanitize=address -o - %s | FileCheck %s --check-prefix=SANITIZE
+// Check -fsplit-bitfields will be ignored since sanitizer is enabled.
+
+struct S1 {
+ unsigned f1:2;
+ unsigned f2:6;
+ unsigned f3:8;
+ unsigned f4:4;
+ unsigned f5:8;
+};
+
+S1 a1;
+unsigned read8_1() {
+ // CHECK-LABEL: @_Z7read8_1v
+ // CHECK: %bf.load = load i8, i8* getelementptr inbounds (%struct.S1, %struct.S1* @a1, i32 0, i32 1), align 1
+ // CHECK-NEXT: %bf.cast = zext i8 %bf.load to i32
+ // CHECK-NEXT: ret i32 %bf.cast
+ // SANITIZE-LABEL: @_Z7read8_1v
+ // SANITIZE: %bf.load = load i32, i32* getelementptr inbounds {{.*}}, align 4
+ // SANITIZE: %bf.lshr = lshr i32 %bf.load, 8
+ // SANITIZE: %bf.clear = and i32 %bf.lshr, 255
+ // SANITIZE: ret i32 %bf.clear
+ return a1.f3;
+}
+void write8_1() {
+ // CHECK-LABEL: @_Z8write8_1v
+ // CHECK: store i8 3, i8* getelementptr inbounds (%struct.S1, %struct.S1* @a1, i32 0, i32 1), align 1
+ // CHECK-NEXT: ret void
+ // SANITIZE-LABEL: @_Z8write8_1v
+ // SANITIZE: %bf.load = load i32, i32* getelementptr inbounds {{.*}}, align 4
+ // SANITIZE-NEXT: %bf.clear = and i32 %bf.load, -65281
+ // SANITIZE-NEXT: %bf.set = or i32 %bf.clear, 768
+ // SANITIZE-NEXT: store i32 %bf.set, i32* getelementptr inbounds {{.*}}, align 4
+ // SANITIZE-NEXT: ret void
+ a1.f3 = 3;
+}
+
+unsigned read8_2() {
+ // CHECK-LABEL: @_Z7read8_2v
+ // CHECK: %bf.load = load i16, i16* getelementptr inbounds (%struct.S1, %struct.S1* @a1, i32 0, i32 2), align 2
+ // CHECK-NEXT: %bf.lshr = lshr i16 %bf.load, 4
+ // CHECK-NEXT: %bf.clear = and i16 %bf.lshr, 255
+ // CHECK-NEXT: %bf.cast = zext i16 %bf.clear to i32
+ // CHECK-NEXT: ret i32 %bf.cast
+ // SANITIZE-LABEL: @_Z7read8_2v
+ // SANITIZE: %bf.load = load i32, i32* getelementptr inbounds {{.*}}, align 4
+ // SANITIZE-NEXT: %bf.lshr = lshr i32 %bf.load, 20
+ // SANITIZE-NEXT: %bf.clear = and i32 %bf.lshr, 255
+ // SANITIZE-NEXT: ret i32 %bf.clear
+ return a1.f5;
+}
+void write8_2() {
+ // CHECK-LABEL: @_Z8write8_2v
+ // CHECK: %bf.load = load i16, i16* getelementptr inbounds (%struct.S1, %struct.S1* @a1, i32 0, i32 2), align 2
+ // CHECK-NEXT: %bf.clear = and i16 %bf.load, -4081
+ // CHECK-NEXT: %bf.set = or i16 %bf.clear, 48
+ // CHECK-NEXT: store i16 %bf.set, i16* getelementptr inbounds (%struct.S1, %struct.S1* @a1, i32 0, i32 2), align 2
+ // CHECK-NEXT: ret void
+ // SANITIZE-LABEL: @_Z8write8_2v
+ // SANITIZE: %bf.load = load i32, i32* getelementptr inbounds {{.*}}, align 4
+ // SANITIZE-NEXT: %bf.clear = and i32 %bf.load, -267386881
+ // SANITIZE-NEXT: %bf.set = or i32 %bf.clear, 3145728
+ // SANITIZE-NEXT: store i32 %bf.set, i32* getelementptr inbounds {{.*}}, align 4
+ // SANITIZE-NEXT: ret void
+ a1.f5 = 3;
+}
+
+struct S2 {
+ unsigned long f1:16;
+ unsigned long f2:16;
+ unsigned long f3:6;
+};
+
+S2 a2;
+unsigned read16_1() {
+ // CHECK-LABEL: @_Z8read16_1v
+ // CHECK: %bf.load = load i16, i16* getelementptr inbounds (%struct.S2, %struct.S2* @a2, i32 0, i32 0), align 8
+ // CHECK-NEXT: %bf.cast = zext i16 %bf.load to i64
+ // CHECK-NEXT: %conv = trunc i64 %bf.cast to i32
+ // CHECK-NEXT: ret i32 %conv
+ // SANITIZE-LABEL: @_Z8read16_1v
+ // SANITIZE: %bf.load = load i64, i64* bitcast {{.*}}, align 8
+ // SANITIZE-NEXT: %bf.clear = and i64 %bf.load, 65535
+ // SANITIZE-NEXT: %conv = trunc i64 %bf.clear to i32
+ // SANITIZE-NEXT: ret i32 %conv
+ return a2.f1;
+}
+unsigned read16_2() {
+ // CHECK-LABEL: @_Z8read16_2v
+ // CHECK: %bf.load = load i16, i16* getelementptr inbounds (%struct.S2, %struct.S2* @a2, i32 0, i32 1), align 2
+ // CHECK-NEXT: %bf.cast = zext i16 %bf.load to i64
+ // CHECK-NEXT: %conv = trunc i64 %bf.cast to i32
+ // CHECK-NEXT: ret i32 %conv
+ // SANITIZE-LABEL: @_Z8read16_2v
+ // SANITIZE: %bf.load = load i64, i64* bitcast {{.*}}, align 8
+ // SANITIZE-NEXT: %bf.lshr = lshr i64 %bf.load, 16
+ // SANITIZE-NEXT: %bf.clear = and i64 %bf.lshr, 65535
+ // SANITIZE-NEXT: %conv = trunc i64 %bf.clear to i32
+ // SANITIZE-NEXT: ret i32 %conv
+ return a2.f2;
+}
+
+void write16_1() {
+ // CHECK-LABEL: @_Z9write16_1v
+ // CHECK: store i16 5, i16* getelementptr inbounds (%struct.S2, %struct.S2* @a2, i32 0, i32 0), align 8
+ // CHECK-NEXT: ret void
+ // SANITIZE-LABEL: @_Z9write16_1v
+ // SANITIZE: %bf.load = load i64, i64* bitcast {{.*}}, align 8
+ // SANITIZE-NEXT: %bf.clear = and i64 %bf.load, -65536
+ // SANITIZE-NEXT: %bf.set = or i64 %bf.clear, 5
+ // SANITIZE-NEXT: store i64 %bf.set, i64* bitcast {{.*}}, align 8
+ // SANITIZE-NEXT: ret void
+ a2.f1 = 5;
+}
+void write16_2() {
+ // CHECK-LABEL: @_Z9write16_2v
+ // CHECK: store i16 5, i16* getelementptr inbounds (%struct.S2, %struct.S2* @a2, i32 0, i32 1), align 2
+ // CHECK-NEXT: ret void
+ // SANITIZE-LABEL: @_Z9write16_2v
+ // SANITIZE: %bf.load = load i64, i64* bitcast {{.*}}, align 8
+ // SANITIZE-NEXT: %bf.clear = and i64 %bf.load, -4294901761
+ // SANITIZE-NEXT: %bf.set = or i64 %bf.clear, 327680
+ // SANITIZE-NEXT: store i64 %bf.set, i64* bitcast {{.*}}, align 8
+ // SANITIZE-NEXT: ret void
+ a2.f2 = 5;
+}
+
+struct S3 {
+ unsigned long f1:14;
+ unsigned long f2:18;
+ unsigned long f3:32;
+};
+
+S3 a3;
+unsigned read32_1() {
+ // CHECK-LABEL: @_Z8read32_1v
+ // CHECK: %bf.load = load i32, i32* getelementptr inbounds (%struct.S3, %struct.S3* @a3, i32 0, i32 1), align 4
+ // CHECK-NEXT: %bf.cast = zext i32 %bf.load to i64
+ // CHECK-NEXT: %conv = trunc i64 %bf.cast to i32
+ // CHECK-NEXT: ret i32 %conv
+ // SANITIZE-LABEL: @_Z8read32_1v
+ // SANITIZE: %bf.load = load i64, i64* getelementptr inbounds {{.*}}, align 8
+ // SANITIZE-NEXT: %bf.lshr = lshr i64 %bf.load, 32
+ // SANITIZE-NEXT: %conv = trunc i64 %bf.lshr to i32
+ // SANITIZE-NEXT: ret i32 %conv
+ return a3.f3;
+}
+void write32_1() {
+ // CHECK-LABEL: @_Z9write32_1v
+ // CHECK: store i32 5, i32* getelementptr inbounds (%struct.S3, %struct.S3* @a3, i32 0, i32 1), align 4
+ // CHECK-NEXT: ret void
+ // SANITIZE-LABEL: @_Z9write32_1v
+ // SANITIZE: %bf.load = load i64, i64* getelementptr inbounds {{.*}}, align 8
+ // SANITIZE-NEXT: %bf.clear = and i64 %bf.load, 4294967295
+ // SANITIZE-NEXT: %bf.set = or i64 %bf.clear, 21474836480
+ // SANITIZE-NEXT: store i64 %bf.set, i64* getelementptr inbounds {{.*}}, align 8
+ // SANITIZE-NEXT: ret void
+ a3.f3 = 5;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/finegrain-bitfield-type.cpp b/src/llvm-project/clang/test/CodeGenCXX/finegrain-bitfield-type.cpp
new file mode 100644
index 0000000..ff02d46
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/finegrain-bitfield-type.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -ffine-grained-bitfield-accesses \
+// RUN: -emit-llvm -o - %s | FileCheck %s
+struct S4 {
+ unsigned long f1:28;
+ unsigned long f2:4;
+ unsigned long f3:12;
+};
+struct S4 a4;
+
+struct S5 {
+ unsigned long f1:28;
+ unsigned long f2:4;
+ unsigned long f3:28;
+ unsigned long f4:4;
+ unsigned long f5:12;
+};
+struct S5 a5;
+
+// CHECK: %struct.S4 = type { i32, i16 }
+// CHECK-NOT: %struct.S4 = type { i48 }
+// CHECK: %struct.S5 = type { i32, i32, i16, [6 x i8] }
+// CHECK-NOT: %struct.S5 = type { i80 }
\ No newline at end of file
diff --git a/src/llvm-project/clang/test/CodeGenCXX/flatten.cpp b/src/llvm-project/clang/test/CodeGenCXX/flatten.cpp
new file mode 100644
index 0000000..9e0f67f
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/flatten.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -triple=x86_64-linux-gnu -std=c++11 %s -emit-llvm -o - | FileCheck %s
+
+void f(void) {}
+
+[[gnu::flatten]]
+// CHECK: define void @_Z1gv()
+void g(void) {
+ // CHECK-NOT: call {{.*}} @_Z1fv
+ f();
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/float128-declarations.cpp b/src/llvm-project/clang/test/CodeGenCXX/float128-declarations.cpp
new file mode 100644
index 0000000..18a25d9
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/float128-declarations.cpp
@@ -0,0 +1,125 @@
+// RUN: %clang_cc1 -emit-llvm -triple powerpc64-unknown-unknown \
+// RUN: -target-feature +float128 -std=c++11 %s -o - | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -triple powerpc64le-unknown-unknown \
+// RUN: -target-feature +float128 -std=c++11 %s -o - | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -triple i386-unknown-linux-gnu -std=c++11 \
+// RUN: %s -o - | FileCheck %s -check-prefix=CHECK-X86
+// RUN: %clang_cc1 -emit-llvm -triple x86_64-unknown-linux-gnu -std=c++11 \
+// RUN: %s -o - | FileCheck %s -check-prefix=CHECK-X86
+// RUN: %clang_cc1 -emit-llvm -triple i686-pc-openbsd -std=c++11 \
+// RUN: %s -o - | FileCheck %s -check-prefix=CHECK-X86
+// RUN: %clang_cc1 -emit-llvm -triple amd64-pc-openbsd -std=c++11 \
+// RUN: %s -o - | FileCheck %s -check-prefix=CHECK-X86
+// RUN: %clang_cc1 -emit-llvm -triple i386-pc-solaris2.11 -std=c++11 \
+// RUN: %s -o - | FileCheck %s -check-prefix=CHECK-X86
+// RUN: %clang_cc1 -emit-llvm -triple x86_64-pc-solaris2.11 -std=c++11 \
+// RUN: %s -o - | FileCheck %s -check-prefix=CHECK-X86
+// RUN: %clang_cc1 -emit-llvm -triple i586-pc-haiku -std=c++11 \
+// RUN: %s -o - | FileCheck %s -check-prefix=CHECK-X86
+// RUN: %clang_cc1 -emit-llvm -triple x86_64-unknown-haiku -std=c++11 \
+// RUN: %s -o - | FileCheck %s -check-prefix=CHECK-X86
+//
+/* Various contexts where type __float128 can appear. The different check
+ prefixes are due to different mangling on X86. */
+
+/* Namespace */
+namespace {
+ __float128 f1n;
+ __float128 f2n = 33.q;
+ __float128 arr1n[10];
+ __float128 arr2n[] = { 1.2q, 3.0q, 3.e11q };
+ const volatile __float128 func1n(const __float128 &arg) {
+ return arg + f2n + arr1n[4] - arr2n[1];
+ }
+}
+
+/* File */
+__float128 f1f;
+__float128 f2f = 32.4q;
+static __float128 f3f = f2f;
+__float128 arr1f[10];
+__float128 arr2f[] = { -1.2q, -3.0q, -3.e11q };
+__float128 func1f(__float128 arg);
+
+/* Class */
+class C1 {
+ __float128 f1c;
+ static const __float128 f2c;
+ volatile __float128 f3c;
+public:
+ C1(__float128 arg) : f1c(arg), f3c(arg) { }
+ __float128 func1c(__float128 arg ) {
+ return f1c + arg;
+ }
+ static __float128 func2c(__float128 arg) {
+ return arg * C1::f2c;
+ }
+};
+
+/* Template */
+template <class C> C func1t(C arg) { return arg * 2.q; }
+template <class C> struct S1 {
+ C mem1;
+};
+template <> struct S1<__float128> {
+ __float128 mem2;
+};
+
+/* Local */
+int main(void) {
+ __float128 f1l = 123e220q;
+ __float128 f2l = -0.q;
+ __float128 f3l = 1.189731495357231765085759326628007e4932q;
+ C1 c1(f1l);
+ S1<__float128> s1 = { 132.q };
+ __float128 f4l = func1n(f1l) + func1f(f2l) + c1.func1c(f3l) + c1.func2c(f1l) +
+ func1t(f1l) + s1.mem2 - f1n + f2n;
+#if (__cplusplus >= 201103L)
+ auto f5l = -1.q, *f6l = &f2l, f7l = func1t(f3l);
+#endif
+ __float128 f8l = f4l++;
+ __float128 arr1l[] = { -1.q, -0.q, -11.q };
+}
+// CHECK-DAG: @_ZN12_GLOBAL__N_13f1nE = internal global fp128 0xL00000000000000000000000000000000
+// CHECK-DAG: @_ZN12_GLOBAL__N_13f2nE = internal global fp128 0xL00000000000000004004080000000000
+// CHECK-DAG: @_ZN12_GLOBAL__N_15arr1nE = internal global [10 x fp128]
+// CHECK-DAG: @_ZN12_GLOBAL__N_15arr2nE = internal global [3 x fp128] [fp128 0xL33333333333333333FFF333333333333, fp128 0xL00000000000000004000800000000000, fp128 0xL00000000000000004025176592E00000]
+// CHECK-DAG: define internal fp128 @_ZN12_GLOBAL__N_16func1nERKU10__float128(fp128*
+// CHECK-DAG: @f1f = global fp128 0xL00000000000000000000000000000000
+// CHECK-DAG: @f2f = global fp128 0xL33333333333333334004033333333333
+// CHECK-DAG: @arr1f = global [10 x fp128]
+// CHECK-DAG: @arr2f = global [3 x fp128] [fp128 0xL3333333333333333BFFF333333333333, fp128 0xL0000000000000000C000800000000000, fp128 0xL0000000000000000C025176592E00000]
+// CHECK-DAG: declare fp128 @_Z6func1fU10__float128(fp128)
+// CHECK-DAG: define linkonce_odr void @_ZN2C1C2EU10__float128(%class.C1* %this, fp128 %arg)
+// CHECK-DAG: define linkonce_odr fp128 @_ZN2C16func2cEU10__float128(fp128 %arg)
+// CHECK-DAG: define linkonce_odr fp128 @_Z6func1tIU10__float128ET_S0_(fp128 %arg)
+// CHECK-DAG: @__const.main.s1 = private unnamed_addr constant %struct.S1 { fp128 0xL00000000000000004006080000000000 }
+// CHECK-DAG: store fp128 0xLF0AFD0EBFF292DCE42E0B38CDD83F26F, fp128* %f1l, align 16
+// CHECK-DAG: store fp128 0xL00000000000000008000000000000000, fp128* %f2l, align 16
+// CHECK-DAG: store fp128 0xLFFFFFFFFFFFFFFFF7FFEFFFFFFFFFFFF, fp128* %f3l, align 16
+// CHECK-DAG: store fp128 0xL0000000000000000BFFF000000000000, fp128* %f5l, align 16
+// CHECK-DAG: [[F4L:%[a-z0-9]+]] = load fp128, fp128* %f4l
+// CHECK-DAG: [[INC:%[a-z0-9]+]] = fadd fp128 [[F4L]], 0xL00000000000000003FFF000000000000
+// CHECK-DAG: store fp128 [[INC]], fp128* %f4l
+
+// CHECK-X86-DAG: @_ZN12_GLOBAL__N_13f1nE = internal global fp128 0xL00000000000000000000000000000000
+// CHECK-X86-DAG: @_ZN12_GLOBAL__N_13f2nE = internal global fp128 0xL00000000000000004004080000000000
+// CHECK-X86-DAG: @_ZN12_GLOBAL__N_15arr1nE = internal global [10 x fp128]
+// CHECK-X86-DAG: @_ZN12_GLOBAL__N_15arr2nE = internal global [3 x fp128] [fp128 0xL33333333333333333FFF333333333333, fp128 0xL00000000000000004000800000000000, fp128 0xL00000000000000004025176592E00000]
+// CHECK-X86-DAG: define internal fp128 @_ZN12_GLOBAL__N_16func1nERKg(fp128*
+// CHECK-X86-DAG: @f1f = global fp128 0xL00000000000000000000000000000000
+// CHECK-X86-DAG: @f2f = global fp128 0xL33333333333333334004033333333333
+// CHECK-X86-DAG: @arr1f = global [10 x fp128]
+// CHECK-X86-DAG: @arr2f = global [3 x fp128] [fp128 0xL3333333333333333BFFF333333333333, fp128 0xL0000000000000000C000800000000000, fp128 0xL0000000000000000C025176592E00000]
+// CHECK-X86-DAG: declare fp128 @_Z6func1fg(fp128)
+// CHECK-X86-DAG: define linkonce_odr void @_ZN2C1C2Eg(%class.C1* %this, fp128 %arg)
+// CHECK-X86-DAG: define linkonce_odr fp128 @_ZN2C16func2cEg(fp128 %arg)
+// CHECK-X86-DAG: define linkonce_odr fp128 @_Z6func1tIgET_S0_(fp128 %arg)
+// CHECK-X86-DAG: @__const.main.s1 = private unnamed_addr constant %struct.S1 { fp128 0xL00000000000000004006080000000000 }
+// CHECK-X86-DAG: store fp128 0xLF0AFD0EBFF292DCE42E0B38CDD83F26F, fp128* %f1l, align 16
+// CHECK-X86-DAG: store fp128 0xL00000000000000008000000000000000, fp128* %f2l, align 16
+// CHECK-X86-DAG: store fp128 0xLFFFFFFFFFFFFFFFF7FFEFFFFFFFFFFFF, fp128* %f3l, align 16
+// CHECK-X86-DAG: store fp128 0xL0000000000000000BFFF000000000000, fp128* %f5l, align 16
+// CHECK-X86-DAG: [[F4L:%[a-z0-9]+]] = load fp128, fp128* %f4l
+// CHECK-X86-DAG: [[INC:%[a-z0-9]+]] = fadd fp128 [[F4L]], 0xL00000000000000003FFF000000000000
+// CHECK-X86-DAG: store fp128 [[INC]], fp128* %f4l
diff --git a/src/llvm-project/clang/test/CodeGenCXX/float16-declarations.cpp b/src/llvm-project/clang/test/CodeGenCXX/float16-declarations.cpp
new file mode 100644
index 0000000..7d07eac
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/float16-declarations.cpp
@@ -0,0 +1,143 @@
+// RUN: %clang -std=c++11 --target=aarch64-arm--eabi -S -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-AARCH64
+
+/* Various contexts where type _Float16 can appear. */
+
+
+/* Namespace */
+
+namespace {
+ _Float16 f1n;
+// CHECK-DAG: @_ZN12_GLOBAL__N_13f1nE = internal global half 0xH0000, align 2
+
+ _Float16 f2n = 33.f16;
+// CHECK-DAG: @_ZN12_GLOBAL__N_13f2nE = internal global half 0xH5020, align 2
+
+ _Float16 arr1n[10];
+// CHECK-AARCH64-DAG: @_ZN12_GLOBAL__N_15arr1nE = internal global [10 x half] zeroinitializer, align 2
+
+ _Float16 arr2n[] = { 1.2, 3.0, 3.e4 };
+// CHECK-DAG: @_ZN12_GLOBAL__N_15arr2nE = internal global [3 x half] [half 0xH3CCD, half 0xH4200, half 0xH7753], align 2
+
+ const volatile _Float16 func1n(const _Float16 &arg) {
+ return arg + f2n + arr1n[4] - arr2n[1];
+ }
+}
+
+
+/* File */
+
+_Float16 f1f;
+// CHECK-AARCH64-DAG: @f1f = dso_local global half 0xH0000, align 2
+
+_Float16 f2f = 32.4;
+// CHECK-DAG: @f2f = dso_local global half 0xH500D, align 2
+
+_Float16 arr1f[10];
+// CHECK-AARCH64-DAG: @arr1f = dso_local global [10 x half] zeroinitializer, align 2
+
+_Float16 arr2f[] = { -1.2, -3.0, -3.e4 };
+// CHECK-DAG: @arr2f = dso_local global [3 x half] [half 0xHBCCD, half 0xHC200, half 0xHF753], align 2
+
+_Float16 func1f(_Float16 arg);
+
+
+/* Class */
+
+class C1 {
+ _Float16 f1c;
+
+ static const _Float16 f2c;
+// CHECK-DAG: @_ZN2C13f2cE = external dso_local constant half, align 2
+
+ volatile _Float16 f3c;
+
+public:
+ C1(_Float16 arg) : f1c(arg), f3c(arg) { }
+// Check that we mangle _Float16 to DF16_
+// CHECK-DAG: define linkonce_odr dso_local void @_ZN2C1C2EDF16_(%class.C1*{{.*}}, half{{.*}})
+
+ _Float16 func1c(_Float16 arg ) {
+ return f1c + arg;
+ }
+// CHECK-DAG: define linkonce_odr dso_local half @_ZN2C16func1cEDF16_(%class.C1*{{.*}}, half{{.*}})
+
+ static _Float16 func2c(_Float16 arg) {
+ return arg * C1::f2c;
+ }
+// CHECK-DAG: define linkonce_odr dso_local half @_ZN2C16func2cEDF16_(half{{.*}})
+};
+
+/* Template */
+
+template <class C> C func1t(C arg) {
+ return arg * 2.f16;
+}
+// CHECK-DAG: define linkonce_odr dso_local half @_Z6func1tIDF16_ET_S0_(half{{.*}})
+
+template <class C> struct S1 {
+ C mem1;
+};
+
+template <> struct S1<_Float16> {
+ _Float16 mem2;
+};
+
+
+/* Local */
+
+extern int printf (const char *__restrict __format, ...);
+
+int main(void) {
+ _Float16 f1l = 1e3f16;
+// CHECK-DAG: store half 0xH63D0, half* %{{.*}}, align 2
+
+ _Float16 f2l = -0.f16;
+// CHECK-DAG: store half 0xH8000, half* %{{.*}}, align 2
+
+ _Float16 f3l = 1.000976562;
+// CHECK-DAG: store half 0xH3C01, half* %{{.*}}, align 2
+
+ C1 c1(f1l);
+// CHECK-DAG: [[F1L:%[a-z0-9]+]] = load half, half* %{{.*}}, align 2
+// CHECK-DAG: call void @_ZN2C1C2EDF16_(%class.C1* %{{.*}}, half %{{.*}})
+
+ S1<_Float16> s1 = { 132.f16 };
+// CHECK-DAG: @__const.main.s1 = private unnamed_addr constant %struct.S1 { half 0xH5820 }, align 2
+// CHECK-DAG: [[S1:%[0-9]+]] = bitcast %struct.S1* %{{.*}} to i8*
+// CHECK-DAG: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 2 [[S1]], i8* align 2 bitcast (%struct.S1* @__const.main.s1 to i8*), i64 2, i1 false)
+
+ _Float16 f4l = func1n(f1l) + func1f(f2l) + c1.func1c(f3l) + c1.func2c(f1l) +
+ func1t(f1l) + s1.mem2 - f1n + f2n;
+
+ auto f5l = -1.f16, *f6l = &f2l, f7l = func1t(f3l);
+// CHECK-DAG: store half 0xHBC00, half* %{{.*}}, align 2
+// CHECK-DAG: store half* %{{.*}}, half** %{{.*}}, align 8
+
+ _Float16 f8l = f4l++;
+// CHECK-DAG: %{{.*}} = load half, half* %{{.*}}, align 2
+// CHECK-DAG: [[INC:%[a-z0-9]+]] = fadd half {{.*}}, 0xH3C00
+// CHECK-DAG: store half [[INC]], half* %{{.*}}, align 2
+
+ _Float16 arr1l[] = { -1.f16, -0.f16, -11.f16 };
+// CHECK-DAG: @__const.main.arr1l = private unnamed_addr constant [3 x half] [half 0xHBC00, half 0xH8000, half 0xHC980], align 2
+
+ float cvtf = f2n;
+//CHECK-DAG: [[H2F:%[a-z0-9]+]] = fpext half {{%[0-9]+}} to float
+//CHECK-DAG: store float [[H2F]], float* %{{.*}}, align 4
+
+ double cvtd = f2n;
+//CHECK-DAG: [[H2D:%[a-z0-9]+]] = fpext half {{%[0-9]+}} to double
+//CHECK-DAG: store double [[H2D]], double* %{{.*}}, align 8
+
+
+ long double cvtld = f2n;
+//CHECK-AARCh64-DAG: [[H2LD:%[a-z0-9]+]] = fpext half {{%[0-9]+}} to fp128
+//CHECK-AARCh64-DAG: store fp128 [[H2LD]], fp128* %{{.*}}, align 16
+
+ _Float16 f2h = 42.0f;
+//CHECK-DAG: store half 0xH5140, half* %{{.*}}, align 2
+ _Float16 d2h = 42.0;
+//CHECK-DAG: store half 0xH5140, half* %{{.*}}, align 2
+ _Float16 ld2h = 42.0l;
+//CHECK-DAG:store half 0xH5140, half* %{{.*}}, align 2
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/for-range-temporaries.cpp b/src/llvm-project/clang/test/CodeGenCXX/for-range-temporaries.cpp
new file mode 100644
index 0000000..a03bb0a
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/for-range-temporaries.cpp
@@ -0,0 +1,146 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -std=c++11 -emit-llvm -o - -UDESUGAR %s | opt -instnamer -S | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -std=c++11 -emit-llvm -o - -DDESUGAR %s | opt -instnamer -S | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -std=c++11 -emit-llvm -o - -UDESUGAR -DTEMPLATE %s | opt -instnamer -S | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -std=c++11 -emit-llvm -o - -DDESUGAR -DTEMPLATE %s | opt -instnamer -S | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -std=c++11 -emit-llvm -o - -UDESUGAR -DTEMPLATE -DDEPENDENT %s | opt -instnamer -S | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -std=c++11 -emit-llvm -o - -DDESUGAR -DTEMPLATE -DDEPENDENT %s | opt -instnamer -S | FileCheck %s
+
+struct A {
+ A();
+ A(const A &);
+ ~A();
+};
+
+struct B {
+ B();
+ B(const B &);
+ ~B();
+};
+
+struct C {
+ C(const B &);
+ C(const C &);
+ ~C();
+};
+
+struct E;
+struct D {
+ D(const C &);
+ D(const D &);
+ ~D();
+};
+E begin(D);
+E end(D);
+
+struct F;
+struct G;
+struct H;
+struct E {
+ E(const E &);
+ ~E();
+ F operator*();
+ G operator++();
+ H operator!=(const E &o);
+};
+
+struct I;
+struct F {
+ F(const F &);
+ ~F();
+ operator I();
+};
+
+struct G {
+ G(const G &);
+ ~G();
+ operator bool();
+};
+
+struct H {
+ H(const H &);
+ ~H();
+ operator bool();
+};
+
+struct I {
+ I(const I &);
+ ~I();
+};
+
+void body(const I &);
+
+#ifdef TEMPLATE
+#ifdef DEPENDENT
+template<typename D>
+#else
+template<typename>
+#endif
+#endif
+void for_temps() {
+ A a;
+#ifdef DESUGAR
+ {
+ auto && __range = D(B());
+ for (auto __begin = begin(__range), __end = end(__range);
+ __begin != __end; ++__begin) {
+ I i = *__begin;
+ body(i);
+ }
+ }
+#else
+ for (I i : D(B())) {
+ body(i);
+ }
+#endif
+}
+
+#ifdef TEMPLATE
+template void for_temps<D>();
+#endif
+
+// CHECK: define {{.*}}for_temps
+// CHECK: call void @_ZN1AC1Ev(
+// CHECK: call void @_ZN1BC1Ev(
+// CHECK: call void @_ZN1CC1ERK1B(
+// CHECK: call void @_ZN1DC1ERK1C(
+// CHECK: call void @_ZN1CD1Ev(
+// CHECK: call void @_ZN1BD1Ev(
+// CHECK: call void @_ZN1DC1ERKS_(
+// CHECK: call void @_Z5begin1D(
+// CHECK: call void @_ZN1DD1Ev(
+// CHECK: call void @_ZN1DC1ERKS_(
+// CHECK: call void @_Z3end1D(
+// CHECK: call void @_ZN1DD1Ev(
+// CHECK: br label %[[COND:.*]]
+
+// CHECK: [[COND]]:
+// CHECK: call void @_ZN1EneERKS_(
+// CHECK: %[[CMP:.*]] = call zeroext i1 @_ZN1HcvbEv(
+// CHECK: call void @_ZN1HD1Ev(
+// CHECK: br i1 %[[CMP]], label %[[BODY:.*]], label %[[CLEANUP:.*]]
+
+// CHECK: [[CLEANUP]]:
+// CHECK: call void @_ZN1ED1Ev(
+// CHECK: call void @_ZN1ED1Ev(
+// In for-range:
+// call void @_ZN1DD1Ev(
+// CHECK: br label %[[END:.*]]
+
+// CHECK: [[BODY]]:
+// CHECK: call void @_ZN1EdeEv(
+// CHECK: call void @_ZN1Fcv1IEv(
+// CHECK: call void @_ZN1FD1Ev(
+// CHECK: call void @_Z4bodyRK1I(
+// CHECK: call void @_ZN1ID1Ev(
+// CHECK: br label %[[INC:.*]]
+
+// CHECK: [[INC]]:
+// CHECK: call void @_ZN1EppEv(
+// CHECK: call void @_ZN1GD1Ev(
+// CHECK: br label %[[COND]]
+
+// CHECK: [[END]]:
+// In desugared version:
+// call void @_ZN1DD1Ev(
+// CHECK: call void @_ZN1AD1Ev(
+// CHECK: ret void
diff --git a/src/llvm-project/clang/test/CodeGenCXX/for-range.cpp b/src/llvm-project/clang/test/CodeGenCXX/for-range.cpp
new file mode 100644
index 0000000..8124129
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/for-range.cpp
@@ -0,0 +1,126 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -std=c++11 -emit-llvm -o - %s | opt -instnamer -S | FileCheck %s
+
+struct A {
+ A();
+ A(const A&);
+ ~A();
+};
+
+struct B {
+ B();
+ B(const B&);
+ ~B();
+};
+
+struct C {
+ C();
+ C(const C&);
+ ~C();
+};
+
+struct D {
+ D();
+ D(const D&);
+ ~D();
+
+ B *begin();
+ B *end();
+};
+
+B *begin(C&);
+B *end(C&);
+
+extern B array[5];
+
+// CHECK-LABEL: define void @_Z9for_arrayv(
+void for_array() {
+ // CHECK: call void @_ZN1AC1Ev(%struct.A* [[A:.*]])
+ A a;
+ for (B b : array) {
+ // CHECK-NOT: 5begin
+ // CHECK-NOT: 3end
+ // CHECK: getelementptr {{.*}}, i32 0
+ // CHECK: getelementptr {{.*}}, i64 5
+ // CHECK: br label %[[COND:.*]]
+
+ // CHECK: [[COND]]:
+ // CHECK: %[[CMP:.*]] = icmp ne
+ // CHECK: br i1 %[[CMP]], label %[[BODY:.*]], label %[[END:.*]]
+
+ // CHECK: [[BODY]]:
+ // CHECK: call void @_ZN1BC1ERKS_(
+ // CHECK: call void @_ZN1BD1Ev(
+ // CHECK: br label %[[INC:.*]]
+
+ // CHECK: [[INC]]:
+ // CHECK: getelementptr {{.*}} i32 1
+ // CHECK: br label %[[COND]]
+ }
+ // CHECK: [[END]]:
+ // CHECK: call void @_ZN1AD1Ev(%struct.A* [[A]])
+ // CHECK: ret void
+}
+
+// CHECK-LABEL: define void @_Z9for_rangev(
+void for_range() {
+ // CHECK: call void @_ZN1AC1Ev(%struct.A* [[A:.*]])
+ A a;
+ for (B b : C()) {
+ // CHECK: call void @_ZN1CC1Ev(
+ // CHECK: = call %struct.B* @_Z5beginR1C(
+ // CHECK: = call %struct.B* @_Z3endR1C(
+ // CHECK: br label %[[COND:.*]]
+
+ // CHECK: [[COND]]:
+ // CHECK: %[[CMP:.*]] = icmp ne
+ // CHECK: br i1 %[[CMP]], label %[[BODY:.*]], label %[[CLEANUP:.*]]
+
+ // CHECK: [[CLEANUP]]:
+ // CHECK: call void @_ZN1CD1Ev(
+ // CHECK: br label %[[END:.*]]
+
+ // CHECK: [[BODY]]:
+ // CHECK: call void @_ZN1BC1ERKS_(
+ // CHECK: call void @_ZN1BD1Ev(
+ // CHECK: br label %[[INC:.*]]
+
+ // CHECK: [[INC]]:
+ // CHECK: getelementptr {{.*}} i32 1
+ // CHECK: br label %[[COND]]
+ }
+ // CHECK: [[END]]:
+ // CHECK: call void @_ZN1AD1Ev(%struct.A* [[A]])
+ // CHECK: ret void
+}
+
+// CHECK-LABEL: define void @_Z16for_member_rangev(
+void for_member_range() {
+ // CHECK: call void @_ZN1AC1Ev(%struct.A* [[A:.*]])
+ A a;
+ for (B b : D()) {
+ // CHECK: call void @_ZN1DC1Ev(
+ // CHECK: = call %struct.B* @_ZN1D5beginEv(
+ // CHECK: = call %struct.B* @_ZN1D3endEv(
+ // CHECK: br label %[[COND:.*]]
+
+ // CHECK: [[COND]]:
+ // CHECK: %[[CMP:.*]] = icmp ne
+ // CHECK: br i1 %[[CMP]], label %[[BODY:.*]], label %[[CLEANUP:.*]]
+
+ // CHECK: [[CLEANUP]]:
+ // CHECK: call void @_ZN1DD1Ev(
+ // CHECK: br label %[[END:.*]]
+
+ // CHECK: [[BODY]]:
+ // CHECK: call void @_ZN1BC1ERKS_(
+ // CHECK: call void @_ZN1BD1Ev(
+ // CHECK: br label %[[INC:.*]]
+
+ // CHECK: [[INC]]:
+ // CHECK: getelementptr {{.*}} i32 1
+ // CHECK: br label %[[COND]]
+ }
+ // CHECK: [[END]]:
+ // CHECK: call void @_ZN1AD1Ev(%struct.A* [[A]])
+ // CHECK: ret void
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/forward-enum.cpp b/src/llvm-project/clang/test/CodeGenCXX/forward-enum.cpp
new file mode 100644
index 0000000..685e4f3
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/forward-enum.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin11.0.0 -emit-llvm -o - %s | FileCheck %s
+
+enum MyEnum : char;
+void bar(MyEnum value) { }
+
+// CHECK-LABEL: define void @_Z3foo6MyEnum
+void foo(MyEnum value)
+{
+ // CHECK: call void @_Z3bar6MyEnum(i8 signext
+ bar(value);
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/fp16-mangle.cpp b/src/llvm-project/clang/test/CodeGenCXX/fp16-mangle.cpp
new file mode 100644
index 0000000..5827fd5
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/fp16-mangle.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -emit-llvm -o - -triple arm-none-linux-gnueabi %s | FileCheck %s
+
+// CHECK: @_ZN1SIDhDhE1iE = global i32 3
+template <typename T, typename U> struct S { static int i; };
+template <> int S<__fp16, __fp16>::i = 3;
+
+// CHECK-LABEL: define void @_Z1fPDh(half* %x)
+void f (__fp16 *x) { }
+
+// CHECK-LABEL: define void @_Z1gPDhS_(half* %x, half* %y)
+void g (__fp16 *x, __fp16 *y) { }
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/fp16-overload.cpp b/src/llvm-project/clang/test/CodeGenCXX/fp16-overload.cpp
new file mode 100644
index 0000000..7562210
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/fp16-overload.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -emit-llvm -o - -triple arm-none-linux-gnueabi %s | FileCheck %s
+
+extern int foo(float x);
+extern int foo(double x);
+
+__fp16 a;
+
+// CHECK: call i32 @_Z3foof
+// CHECK-NOT: call i32 @_Z3food
+int bar (void) { return foo(a); }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/friend-redecl.cpp b/src/llvm-project/clang/test/CodeGenCXX/friend-redecl.cpp
new file mode 100644
index 0000000..18292cd
--- /dev/null
+++ b/src/llvm-project/clang/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/src/llvm-project/clang/test/CodeGenCXX/funcattrs-global-ctor-dtor.cpp b/src/llvm-project/clang/test/CodeGenCXX/funcattrs-global-ctor-dtor.cpp
new file mode 100644
index 0000000..b98cb24
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/funcattrs-global-ctor-dtor.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 %s -triple x86_64-apple-darwin -S -stack-protector 2 -emit-llvm -o - | FileCheck %s
+
+class A {
+ public:
+ virtual ~A() {}
+};
+
+A g;
+
+// CHECK: define internal void @__cxx_global_var_init() [[ATTR0:#[0-9]+]]
+// CHECK: define internal void @_GLOBAL__sub_I_funcattrs_global_ctor_dtor.cpp() [[ATTR0]]
+// CHECK: attributes [[ATTR0]] = {{{.*}} sspstrong {{.*}}}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/funcsig.cpp b/src/llvm-project/clang/test/CodeGenCXX/funcsig.cpp
new file mode 100644
index 0000000..5328ff9
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/funcsig.cpp
@@ -0,0 +1,51 @@
+// RUN: %clang_cc1 -std=c++11 -triple i686-pc-win32 %s -fms-extensions -fno-rtti -emit-llvm -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-CXX
+// RUN: %clang_cc1 -x c -triple i686-pc-win32 %s -fms-extensions -fno-rtti -emit-llvm -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-C
+
+// Similar to predefined-expr.cpp, but not as exhaustive, since it's basically
+// equivalent to __PRETTY_FUNCTION__.
+
+#ifdef __cplusplus
+extern "C"
+#endif
+int printf(const char *, ...);
+
+void funcNoProto() {
+ printf("__FUNCSIG__ %s\n\n", __FUNCSIG__);
+}
+// CHECK-C: @"??_C@_0BL@IHLLLCAO@void?5__cdecl?5funcNoProto?$CI?$CJ?$AA@" = linkonce_odr dso_local unnamed_addr constant [27 x i8] c"void __cdecl funcNoProto()\00"
+// CHECK-CXX: @"??_C@_0BP@PJOECCJN@void?5__cdecl?5funcNoProto?$CIvoid?$CJ?$AA@" = linkonce_odr dso_local unnamed_addr constant [31 x i8] c"void __cdecl funcNoProto(void)\00"
+
+void funcNoParams(void) {
+ printf("__FUNCSIG__ %s\n\n", __FUNCSIG__);
+}
+// CHECK: @"??_C@_0CA@GBIDFNBN@void?5__cdecl?5funcNoParams?$CIvoid?$CJ?$AA@" = linkonce_odr dso_local unnamed_addr constant [32 x i8] c"void __cdecl funcNoParams(void)\00"
+
+void freeFunc(int *p, char c) {
+ printf("__FUNCSIG__ %s\n\n", __FUNCSIG__);
+}
+// CHECK: @"??_C@_0CD@KLGMNNL@void?5__cdecl?5freeFunc?$CIint?5?$CK?0?5cha@" = linkonce_odr dso_local unnamed_addr constant [{{.*}} x i8] c"void __cdecl freeFunc(int *, char)\00"
+
+#ifdef __cplusplus
+void funcVarargs(...) {
+ printf("__FUNCSIG__ %s\n\n", __FUNCSIG__);
+}
+// CHECK-CXX: @"??_C@_0BO@BOBPLEKP@void?5__cdecl?5funcVarargs?$CI?4?4?4?$CJ?$AA@" = linkonce_odr dso_local unnamed_addr constant [30 x i8] c"void __cdecl funcVarargs(...)\00"
+
+struct TopLevelClass {
+ void topLevelMethod(int *, char);
+};
+void TopLevelClass::topLevelMethod(int *, char) {
+ printf("__FUNCSIG__ %s\n\n", __FUNCSIG__);
+}
+// CHECK-CXX: @"??_C@_0DL@OBHNMDP@void?5__thiscall?5TopLevelClass?3?3t@" = linkonce_odr dso_local unnamed_addr constant [{{.*}} x i8] c"void __thiscall TopLevelClass::topLevelMethod(int *, char)\00"
+
+namespace NS {
+struct NamespacedClass {
+ void namespacedMethod(int *, char);
+};
+void NamespacedClass::namespacedMethod(int *, char) {
+ printf("__FUNCSIG__ %s\n\n", __FUNCSIG__);
+}
+// CHECK-CXX: @"??_C@_0ED@PFDKIEBA@void?5__thiscall?5NS?3?3NamespacedCl@" = linkonce_odr dso_local unnamed_addr constant [{{.*}} x i8] c"void __thiscall NS::NamespacedClass::namespacedMethod(int *, char)\00"
+}
+#endif
diff --git a/src/llvm-project/clang/test/CodeGenCXX/function-template-explicit-specialization.cpp b/src/llvm-project/clang/test/CodeGenCXX/function-template-explicit-specialization.cpp
new file mode 100644
index 0000000..ed6cf84
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/function-template-explicit-specialization.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple %s -o - | FileCheck %s
+
+template<typename T> void a(T);
+template<> void a(int) {}
+
+// CHECK-LABEL: define {{.*}}void @_Z1aIiEvT_
+
+namespace X {
+template<typename T> void b(T);
+template<> void b(int) {}
+}
+
+// CHECK-LABEL: define {{.*}}void @_ZN1X1bIiEEvT_
diff --git a/src/llvm-project/clang/test/CodeGenCXX/function-template-specialization.cpp b/src/llvm-project/clang/test/CodeGenCXX/function-template-specialization.cpp
new file mode 100644
index 0000000..7728f3d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/function-template-specialization.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple %s -o - | FileCheck %s
+
+// CHECK-DAG: _ZZN7PR219047GetDataIiEERKibE1i = internal global i32 4
+// CHECK-DAG: _ZZN7PR219047GetDataIiEERKibE1i_0 = internal global i32 2
+
+template<typename T, typename U>
+T* next(T* ptr, const U& diff);
+
+template<typename T, typename U>
+T* next(T* ptr, const U& diff) {
+ return ptr + diff;
+}
+
+void test(int *iptr, float *fptr, int diff) {
+ // CHECK: _Z4nextIiiEPT_S1_RKT0_
+ iptr = next(iptr, diff);
+
+ // CHECK: _Z4nextIfiEPT_S1_RKT0_
+ fptr = next(fptr, diff);
+}
+
+template<typename T, typename U>
+T* next(T* ptr, const U& diff);
+
+void test2(int *iptr, double *dptr, int diff) {
+ iptr = next(iptr, diff);
+
+ // CHECK: _Z4nextIdiEPT_S1_RKT0_
+ dptr = next(dptr, diff);
+}
+
+namespace PR21904 {
+template <typename>
+const int &GetData(bool);
+
+template <>
+const int &GetData<int>(bool b) {
+ static int i = 4;
+ if (b) {
+ static int i = 2;
+ return i;
+ }
+ return i;
+}
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/global-array-destruction.cpp b/src/llvm-project/clang/test/CodeGenCXX/global-array-destruction.cpp
new file mode 100644
index 0000000..1ae7b72
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/global-array-destruction.cpp
@@ -0,0 +1,62 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm %s -o - | FileCheck %s
+
+extern "C" int printf(...);
+
+int count;
+
+struct S {
+ S() : iS(++count) { printf("S::S(%d)\n", iS); }
+ ~S() { printf("S::~S(%d)\n", iS); }
+ int iS;
+};
+
+
+S arr[2][1];
+S s1;
+S arr1[3];
+static S sarr[4];
+
+int main () {}
+S arr2[2];
+static S sarr1[4];
+S s2;
+S arr3[3];
+
+// CHECK: call {{.*}} @__cxa_atexit
+// CHECK: call {{.*}} @__cxa_atexit
+// CHECK: call {{.*}} @__cxa_atexit
+// CHECK: call {{.*}} @__cxa_atexit
+// CHECK: call {{.*}} @__cxa_atexit
+// CHECK: call {{.*}} @__cxa_atexit
+// CHECK: call {{.*}} @__cxa_atexit
+// CHECK: call {{.*}} @__cxa_atexit
+
+struct T {
+ double d;
+ int n;
+ ~T();
+};
+T t[2][3] = { 1.0, 2, 3.0, 4, 5.0, 6, 7.0, 8, 9.0, 10, 11.0, 12 };
+
+// CHECK: call {{.*}} @__cxa_atexit
+// CHECK: getelementptr inbounds ({{.*}} getelementptr inbounds ([2 x [3 x {{.*}}]], [2 x [3 x {{.*}}]]* @t, i32 0, i32 0, i32 0), i64 6)
+// CHECK: call void @_ZN1TD1Ev
+// CHECK: icmp eq {{.*}} @t
+// CHECK: br i1 {{.*}}
+
+static T t2[2][3] = { 1.0, 2, 3.0, 4, 5.0, 6, 7.0, 8, 9.0, 10, 11.0, 12 };
+
+// CHECK: call {{.*}} @__cxa_atexit
+// CHECK: getelementptr inbounds ({{.*}} getelementptr inbounds ([2 x [3 x {{.*}}]], [2 x [3 x {{.*}}]]* @_ZL2t2, i32 0, i32 0, i32 0), i64 6)
+// CHECK: call void @_ZN1TD1Ev
+// CHECK: icmp eq {{.*}} @_ZL2t2
+// CHECK: br i1 {{.*}}
+
+using U = T[2][3];
+U &&u = U{ {{1.0, 2}, {3.0, 4}, {5.0, 6}}, {{7.0, 8}, {9.0, 10}, {11.0, 12}} };
+
+// CHECK: call {{.*}} @__cxa_atexit
+// CHECK: getelementptr inbounds ({{.*}}* getelementptr inbounds ([2 x [3 x {{.*}}]], [2 x [3 x {{.*}}]]* @_ZGR1u_, i32 0, i32 0, i32 0), i64 6)
+// CHECK: call void @_ZN1TD1Ev
+// CHECK: icmp eq {{.*}} @_ZGR1u_
+// CHECK: br i1 {{.*}}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/global-block-literal-helpers.cpp b/src/llvm-project/clang/test/CodeGenCXX/global-block-literal-helpers.cpp
new file mode 100644
index 0000000..762b5d9
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/global-block-literal-helpers.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -std=c++11 -emit-llvm -fblocks -o - -triple x86_64-apple-darwin10 %s | FileCheck %s
+// rdar://11343499
+
+namespace N {
+ typedef void (^BL)();
+ int func(BL, BL, BL);
+
+// CHECK-LABEL: define internal void @_ZN1N8ArrBlockE_block_invoke(
+// CHECK-LABEL: define internal void @_ZN1N8ArrBlockE_block_invoke_2(
+// CHECK-LABEL: define internal void @_ZN1N8ArrBlockE_block_invoke_3
+ BL ArrBlock [] = { ^{}, ^{}, ^{} };
+
+// CHECK-LABEL: define internal void @_ZN1N4ivalE_block_invoke_4(
+// CHECK-LABEL: define internal void @_ZN1N4ivalE_block_invoke_5(
+// CHECK-LABEL: define internal void @_ZN1N4ivalE_block_invoke_6(
+ int ival = func(^{}, ^{}, ^{});
+
+// CHECK-LABEL: define internal void @_ZN1N9gvarlobalE_block_invoke_7(
+ void (^gvarlobal)(void) = ^{};
+
+ struct S {
+ BL field = ^{};
+ };
+
+// CHECK-LABEL: define internal void @_ZN1N3blfE_block_invoke_8(
+ S blf;
+};
diff --git a/src/llvm-project/clang/test/CodeGenCXX/global-dtor-no-atexit.cpp b/src/llvm-project/clang/test/CodeGenCXX/global-dtor-no-atexit.cpp
new file mode 100644
index 0000000..8621941
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/global-dtor-no-atexit.cpp
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -triple x86_64 %s -fno-use-cxa-atexit -emit-llvm -o - | FileCheck %s
+
+// PR7097
+// RUN: %clang_cc1 -triple x86_64 %s -fno-use-cxa-atexit -mconstructor-aliases -emit-llvm -o - | FileCheck %s
+
+// CHECK: call void @_ZN1AC1Ev([[A:%.*]]* @a)
+// CHECK-NEXT: call i32 @atexit(void ()* @__dtor_a)
+// CHECK: define internal void @__dtor_a() [[NUW:#[0-9]+]]
+// CHECK: call void @_ZN1AD1Ev([[A]]* @a)
+
+// CHECK: call void @_ZN1AC1Ev([[A]]* @b)
+// CHECK-NEXT: call i32 @atexit(void ()* @__dtor_b)
+// CHECK: define internal void @__dtor_b() [[NUW]]
+// CHECK: call void @_ZN1AD1Ev([[A]]* @b)
+
+class A {
+public:
+ A();
+ ~A();
+};
+
+A a, b;
+
+// PR9593
+// CHECK-LABEL: define void @_Z4funcv()
+// CHECK: call i32 @__cxa_guard_acquire(i64* @_ZGVZ4funcvE2a1)
+// CHECK: call void @_ZN1AC1Ev([[A]]* @_ZZ4funcvE2a1)
+// CHECK-NEXT: call i32 @atexit(void ()* @__dtor__ZZ4funcvE2a1)
+// CHECK-NEXT: call void @__cxa_guard_release(i64* @_ZGVZ4funcvE2a1)
+
+// CHECK: call i32 @__cxa_guard_acquire(i64* @_ZGVZ4funcvE2a2)
+// CHECK: call void @_ZN1AC1Ev([[A]]* @_ZZ4funcvE2a2)
+// CHECK-NEXT: call i32 @atexit(void ()* @__dtor__ZZ4funcvE2a2)
+// CHECK-NEXT: call void @__cxa_guard_release(i64* @_ZGVZ4funcvE2a2)
+
+// CHECK: define internal void @__dtor__ZZ4funcvE2a1() [[NUW]]
+// CHECK: call void @_ZN1AD1Ev([[A]]* @_ZZ4funcvE2a1)
+
+// CHECK: define internal void @__dtor__ZZ4funcvE2a2() [[NUW]]
+// CHECK: call void @_ZN1AD1Ev([[A]]* @_ZZ4funcvE2a2)
+
+void func() {
+ static A a1, a2;
+}
+
+// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/global-init-darwin.cpp b/src/llvm-project/clang/test/CodeGenCXX/global-init-darwin.cpp
new file mode 100644
index 0000000..20c13c6
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/global-init-darwin.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple=x86_64-apple-darwin10 -emit-llvm %s -o - |FileCheck %s
+
+struct A {
+ A();
+ ~A();
+};
+
+A a;
+A as[2];
+
+struct B {
+ B();
+ ~B();
+ int f();
+};
+
+int i = B().f();
+
+// CHECK: "__TEXT,__StaticInit,regular,pure_instructions" {
+// CHECK: "__TEXT,__StaticInit,regular,pure_instructions" {
+// CHECK: "__TEXT,__StaticInit,regular,pure_instructions" {
+// CHECK: "__TEXT,__StaticInit,regular,pure_instructions" {
+// CHECK: "__TEXT,__StaticInit,regular,pure_instructions" {
diff --git a/src/llvm-project/clang/test/CodeGenCXX/global-init.cpp b/src/llvm-project/clang/test/CodeGenCXX/global-init.cpp
new file mode 100644
index 0000000..f96e603
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/global-init.cpp
@@ -0,0 +1,211 @@
+// RUN: %clang_cc1 -triple=x86_64-apple-darwin10 -emit-llvm -fexceptions %s -o - |FileCheck %s
+// RUN: %clang_cc1 -triple=x86_64-apple-darwin10 -emit-llvm %s -o - |FileCheck -check-prefix CHECK-NOEXC %s
+// RUN: %clang_cc1 -triple=x86_64-apple-darwin10 -emit-llvm \
+// RUN: -momit-leaf-frame-pointer -mdisable-fp-elim %s -o - \
+// RUN: | FileCheck -check-prefix CHECK-FP %s
+
+struct A {
+ A();
+ ~A();
+};
+
+struct B { B(); ~B(); };
+
+struct C { void *field; };
+
+struct D { ~D(); };
+
+// CHECK: @__dso_handle = external hidden global i8
+// CHECK: @c = global %struct.C zeroinitializer, align 8
+
+// PR6205: The casts should not require global initializers
+// CHECK: @_ZN6PR59741cE = external global %"struct.PR5974::C"
+// CHECK: @_ZN6PR59741aE = global %"struct.PR5974::A"* getelementptr inbounds (%"struct.PR5974::C", %"struct.PR5974::C"* @_ZN6PR59741cE, i32 0, i32 0)
+// CHECK: @_ZN6PR59741bE = global %"struct.PR5974::B"* bitcast (i8* getelementptr (i8, i8* bitcast (%"struct.PR5974::C"* @_ZN6PR59741cE to i8*), i64 4) to %"struct.PR5974::B"*), 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, %struct.A* @a, i32 0, i32 0), i8* @__dso_handle)
+A a;
+
+// CHECK: call void @_ZN1BC1Ev(%struct.B* @b)
+// CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.B*)* @_ZN1BD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.B, %struct.B* @b, i32 0, i32 0), i8* @__dso_handle)
+B b;
+
+// PR6205: this should not require a global initializer
+// CHECK-NOT: call void @_ZN1CC1Ev(%struct.C* @c)
+C c;
+
+// CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.D*)* @_ZN1DD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.D, %struct.D* @d, i32 0, i32 0), i8* @__dso_handle)
+D d;
+
+// <rdar://problem/7458115>
+namespace test1 {
+ int f();
+ const int x = f(); // This has side-effects and gets emitted immediately.
+ const int y = x - 1; // This gets deferred.
+ const int z = ~y; // This also gets deferred, but gets "undeferred" before y.
+ int test() { return z; }
+// CHECK-LABEL: define i32 @_ZN5test14testEv()
+
+ // All of these initializers end up delayed, so we check them later.
+}
+
+// <rdar://problem/8246444>
+namespace test2 {
+ struct allocator { allocator(); ~allocator(); };
+ struct A { A(const allocator &a = allocator()); ~A(); };
+
+ A a;
+// CHECK: call void @_ZN5test29allocatorC1Ev(
+// CHECK: invoke void @_ZN5test21AC1ERKNS_9allocatorE(
+// CHECK: call void @_ZN5test29allocatorD1Ev(
+// CHECK: call i32 @__cxa_atexit({{.*}} @_ZN5test21AD1Ev {{.*}} @_ZN5test21aE
+}
+
+namespace test3 {
+ // Tested at the beginning of the file.
+ const char * const var = "string";
+ extern const char * const var;
+
+ const char *test() { return var; }
+}
+
+namespace test4 {
+ struct A {
+ A();
+ };
+ extern int foo();
+
+ // This needs an initialization function and guard variables.
+ // CHECK: load i8, i8* bitcast (i64* @_ZGVN5test41xE
+ // CHECK: [[CALL:%.*]] = call i32 @_ZN5test43fooEv
+ // CHECK-NEXT: store i32 [[CALL]], i32* @_ZN5test41xE
+ // CHECK-NEXT: store i64 1, i64* @_ZGVN5test41xE
+ __attribute__((weak)) int x = foo();
+}
+
+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;
+}
+
+// PR9570: the indirect field shouldn't crash IR gen.
+namespace test5 {
+ static union {
+ unsigned bar[4096] __attribute__((aligned(128)));
+ };
+}
+
+namespace std { struct type_info; }
+
+namespace test6 {
+ struct A { virtual ~A(); };
+ struct B : A {};
+ extern A *p;
+
+ // We must emit a dynamic initializer for 'q', because it could throw.
+ B *const q = &dynamic_cast<B&>(*p);
+ // CHECK: call void @__cxa_bad_cast()
+ // CHECK: store {{.*}} @_ZN5test6L1qE
+
+ // We don't need to emit 'r' at all, because it has internal linkage, is
+ // unused, and its initialization has no side-effects.
+ B *const r = dynamic_cast<B*>(p);
+ // CHECK-NOT: call void @__cxa_bad_cast()
+ // CHECK-NOT: store {{.*}} @_ZN5test6L1rE
+
+ // This can throw, so we need to emit it.
+ const std::type_info *const s = &typeid(*p);
+ // CHECK: store {{.*}} @_ZN5test6L1sE
+
+ // This can't throw, so we don't.
+ const std::type_info *const t = &typeid(p);
+ // CHECK-NOT: @_ZN5test6L1tE
+
+ extern B *volatile v;
+ // CHECK: store {{.*}} @_ZN5test6L1wE
+ B *const w = dynamic_cast<B*>(v);
+
+ // CHECK: load volatile
+ // CHECK: store {{.*}} @_ZN5test6L1xE
+ const int x = *(volatile int*)0x1234;
+
+ namespace {
+ int a = int();
+ volatile int b = int();
+ int c = a;
+ int d = b;
+ // CHECK-NOT: store {{.*}} @_ZN5test6{{[A-Za-z0-9_]*}}1aE
+ // CHECK-NOT: store {{.*}} @_ZN5test6{{[A-Za-z0-9_]*}}1bE
+ // CHECK-NOT: store {{.*}} @_ZN5test6{{[A-Za-z0-9_]*}}1cE
+ // CHECK: load volatile {{.*}} @_ZN5test6{{[A-Za-z0-9_]*}}1bE
+ // CHECK: store {{.*}} @_ZN5test6{{[A-Za-z0-9_]*}}1dE
+ }
+}
+
+namespace test7 {
+ struct A { A(); };
+ struct B { ~B(); int n; };
+ struct C { C() = default; C(const C&); int n; };
+ struct D {};
+
+ // CHECK: call void @_ZN5test71AC1Ev({{.*}}@_ZN5test7L1aE)
+ const A a = A();
+
+ // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN5test71BD1Ev{{.*}} @_ZN5test7L2b1E
+ // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN5test71BD1Ev{{.*}} @_ZGRN5test72b2E
+ // CHECK: call void @_ZN5test71BD1Ev(
+ // CHECK: store {{.*}} @_ZN5test7L2b3E
+ const B b1 = B();
+ const B &b2 = B();
+ const int b3 = B().n;
+
+ // CHECK-NOT: @_ZN5test7L2c1E
+ // CHECK: call void @llvm.memset{{.*}} @_ZN5test7L2c1E
+ // CHECK-NOT: @_ZN5test7L2c1E
+ // CHECK: @_ZN5test7L2c2E
+ // CHECK-NOT: @_ZN5test7L2c3E
+ // CHECK: @_ZN5test7L2c4E
+ const C c1 = C();
+ const C c2 = static_cast<const C&>(C());
+ const int c3 = C().n;
+ const int c4 = C(C()).n;
+
+ // CHECK-NOT: @_ZN5test7L1dE
+ const D d = D();
+
+ // CHECK: store {{.*}} @_ZN5test71eE
+ int f(), e = f();
+}
+
+
+// At the end of the file, we check that y is initialized before z.
+
+// CHECK: define internal void [[TEST1_Z_INIT:@.*]]()
+// CHECK: load i32, i32* @_ZN5test1L1yE
+// CHECK-NEXT: xor
+// CHECK-NEXT: store i32 {{.*}}, i32* @_ZN5test1L1zE
+// CHECK: define internal void [[TEST1_Y_INIT:@.*]]()
+// CHECK: load i32, i32* @_ZN5test1L1xE
+// CHECK-NEXT: sub
+// CHECK-NEXT: store i32 {{.*}}, i32* @_ZN5test1L1yE
+
+// CHECK: define internal void @_GLOBAL__sub_I_global_init.cpp() #{{[0-9]+}} section "__TEXT,__StaticInit,regular,pure_instructions" {
+// CHECK: call void [[TEST1_Y_INIT]]
+// CHECK: call void [[TEST1_Z_INIT]]
+
+// rdar://problem/8090834: this should be nounwind
+// CHECK-NOEXC: define internal void @_GLOBAL__sub_I_global_init.cpp() [[NUW:#[0-9]+]] section "__TEXT,__StaticInit,regular,pure_instructions" {
+
+// CHECK-NOEXC: attributes [[NUW]] = { noinline nounwind{{.*}} }
+
+// PR21811: attach the appropriate attribute to the global init function
+// CHECK-FP: define internal void @_GLOBAL__sub_I_global_init.cpp() [[NUX:#[0-9]+]] section "__TEXT,__StaticInit,regular,pure_instructions" {
+// CHECK-FP: attributes [[NUX]] = { noinline nounwind {{.*}}"no-frame-pointer-elim-non-leaf"{{.*}} }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/global-llvm-constant.cpp b/src/llvm-project/clang/test/CodeGenCXX/global-llvm-constant.cpp
new file mode 100644
index 0000000..877683e
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/global-llvm-constant.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -o - %s | FileCheck %s
+
+struct A {
+ A() { x = 10; }
+ int x;
+};
+
+const A x;
+
+// CHECK: @_ZL1x = internal global
+
+struct X {
+ int (*fp)(int, int);
+};
+
+int add(int x, int y) { return x + y; }
+
+// CHECK: @x2 = {{(dso_local )?}}constant
+extern const X x2;
+const X x2 = { &add };
+
+struct X1 {
+ mutable int i;
+};
+
+struct X2 {
+ X1 array[3];
+};
+
+// CHECK: @x2b = {{(dso_local )?}}global
+extern const X2 x2b;
+const X2 x2b = { { { 1 }, { 2 }, { 3 } } };
diff --git a/src/llvm-project/clang/test/CodeGenCXX/globalinit-loc.cpp b/src/llvm-project/clang/test/CodeGenCXX/globalinit-loc.cpp
new file mode 100644
index 0000000..e9715a6
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/globalinit-loc.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited %s -o - | FileCheck %s
+// rdar://problem/14985269.
+//
+// Verify that the global init helper function does not get associated
+// with any source location.
+//
+// CHECK: define internal {{.*}}void @_GLOBAL__sub_I_globalinit_loc.cpp({{.*}} {
+// CHECK: !dbg ![[DBG:.*]]
+// CHECK: !DISubprogram(linkageName: "_GLOBAL__sub_I_globalinit_loc.cpp"
+// CHECK-NOT: line:
+// CHECK-SAME: DISPFlagLocalToUnit
+// CHECK-SAME: DISPFlagDefinition
+// CHECK: ![[DBG]] = !DILocation(line: 0,
+# 99 "someheader.h"
+class A {
+public:
+ A();
+ int foo() { return 0; }
+};
+# 5 "main.cpp"
+A a;
+
+int f() {
+ return a.foo();
+}
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/goto.cpp b/src/llvm-project/clang/test/CodeGenCXX/goto.cpp
new file mode 100644
index 0000000..2f5b719
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/goto.cpp
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fcxx-exceptions -fexceptions -emit-llvm -std=c++98 -o - | FileCheck -check-prefix=CHECK -check-prefix=CHECK98 %s
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fcxx-exceptions -fexceptions -emit-llvm -std=c++11 -o - | FileCheck -check-prefix=CHECK -check-prefix=CHECK11 %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-LABEL: 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: [[SEL:%.*]] = alloca i32
+ // CHECK-NEXT: [[V:%.*]] = alloca [[V:%.*]]*,
+ // CHECK-NEXT: [[TMP:%.*]] = alloca [[A]]
+ // CHECK-NEXT: [[CLEANUPACTIVE:%.*]] = alloca i1
+ // CHECK: call void @_ZN5test01AC1Ev([[A]]* [[Y]])
+ // CHECK-NEXT: invoke void @_ZN5test01AC1Ev([[A]]* [[Z]])
+ // CHECK: [[NEW:%.*]] = invoke i8* @_Znwm(i64 1)
+ // CHECK: store i1 true, i1* [[CLEANUPACTIVE]]
+ // CHECK: [[NEWCAST:%.*]] = bitcast i8* [[NEW]] to [[V]]*
+ // CHECK-NEXT: invoke void @_ZN5test01AC1Ev([[A]]* [[TMP]])
+ // CHECK: invoke void @_ZN5test01VC1ERKNS_1AE([[V]]* [[NEWCAST]], [[A]]* dereferenceable({{[0-9]+}}) [[TMP]])
+ // CHECK: store i1 false, i1* [[CLEANUPACTIVE]]
+
+ // CHECK98-NEXT: invoke void @_ZN5test01AD1Ev([[A]]* [[TMP]])
+ // CHECK11-NEXT: call 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/src/llvm-project/clang/test/CodeGenCXX/hidden-dllimport.cpp b/src/llvm-project/clang/test/CodeGenCXX/hidden-dllimport.cpp
new file mode 100644
index 0000000..573b421
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/hidden-dllimport.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc -emit-llvm -fvisibility-inlines-hidden -o - %s | FileCheck %s
+
+// We used to declare this hidden dllimport, which is contradictory.
+
+// CHECK: declare dllimport void @"?bar@foo@@QEAAXXZ"(%struct.foo*)
+
+struct __attribute__((dllimport)) foo {
+ void bar() {}
+};
+void zed(foo *p) { p->bar(); }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/homogeneous-aggregates.cpp b/src/llvm-project/clang/test/CodeGenCXX/homogeneous-aggregates.cpp
new file mode 100644
index 0000000..05fb7f1d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/homogeneous-aggregates.cpp
@@ -0,0 +1,106 @@
+// RUN: %clang_cc1 -triple powerpc64le-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s --check-prefix=PPC
+// RUN: %clang_cc1 -mfloat-abi hard -triple armv7-unknown-linux-gnueabi -emit-llvm -o - %s | FileCheck %s --check-prefix=ARM32
+// RUN: %clang_cc1 -mfloat-abi hard -triple aarch64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s --check-prefix=ARM64
+// RUN: %clang_cc1 -mfloat-abi hard -triple x86_64-unknown-windows-gnu -emit-llvm -o - %s | FileCheck %s --check-prefix=X64
+
+#if defined(__x86_64__)
+#define CC __attribute__((vectorcall))
+#else
+#define CC
+#endif
+
+// Test that C++ classes are correctly classified as homogeneous aggregates.
+
+struct Base1 {
+ int x;
+};
+struct Base2 {
+ double x;
+};
+struct Base3 {
+ double x;
+};
+struct D1 : Base1 { // non-homogeneous aggregate
+ double y, z;
+};
+struct D2 : Base2 { // homogeneous aggregate
+ double y, z;
+};
+struct D3 : Base1, Base2 { // non-homogeneous aggregate
+ double y, z;
+};
+struct D4 : Base2, Base3 { // homogeneous aggregate
+ double y, z;
+};
+
+struct I1 : Base2 {};
+struct I2 : Base2 {};
+struct I3 : Base2 {};
+struct D5 : I1, I2, I3 {}; // homogeneous aggregate
+
+// PPC: define void @_Z7func_D12D1(%struct.D1* noalias sret %agg.result, [3 x i64] %x.coerce)
+// ARM32: define arm_aapcs_vfpcc void @_Z7func_D12D1(%struct.D1* noalias sret %agg.result, [3 x i64] %x.coerce)
+// ARM64: define void @_Z7func_D12D1(%struct.D1* noalias sret %agg.result, %struct.D1* %x)
+// X64: define dso_local x86_vectorcallcc void @"\01_Z7func_D12D1@@24"(%struct.D1* noalias sret %agg.result, %struct.D1* %x)
+D1 CC func_D1(D1 x) { return x; }
+
+// PPC: define [3 x double] @_Z7func_D22D2([3 x double] %x.coerce)
+// ARM32: define arm_aapcs_vfpcc %struct.D2 @_Z7func_D22D2(%struct.D2 %x.coerce)
+// ARM64: define %struct.D2 @_Z7func_D22D2([3 x double] %x.coerce)
+// X64: define dso_local x86_vectorcallcc %struct.D2 @"\01_Z7func_D22D2@@24"(%struct.D2 inreg %x.coerce)
+D2 CC func_D2(D2 x) { return x; }
+
+// PPC: define void @_Z7func_D32D3(%struct.D3* noalias sret %agg.result, [4 x i64] %x.coerce)
+// ARM32: define arm_aapcs_vfpcc void @_Z7func_D32D3(%struct.D3* noalias sret %agg.result, [4 x i64] %x.coerce)
+// ARM64: define void @_Z7func_D32D3(%struct.D3* noalias sret %agg.result, %struct.D3* %x)
+D3 CC func_D3(D3 x) { return x; }
+
+// PPC: define [4 x double] @_Z7func_D42D4([4 x double] %x.coerce)
+// ARM32: define arm_aapcs_vfpcc %struct.D4 @_Z7func_D42D4(%struct.D4 %x.coerce)
+// ARM64: define %struct.D4 @_Z7func_D42D4([4 x double] %x.coerce)
+D4 CC func_D4(D4 x) { return x; }
+
+D5 CC func_D5(D5 x) { return x; }
+// PPC: define [3 x double] @_Z7func_D52D5([3 x double] %x.coerce)
+// ARM32: define arm_aapcs_vfpcc %struct.D5 @_Z7func_D52D5(%struct.D5 %x.coerce)
+
+// The C++ multiple inheritance expansion case is a little more complicated, so
+// do some extra checking.
+//
+// ARM64-LABEL: define %struct.D5 @_Z7func_D52D5([3 x double] %x.coerce)
+// ARM64: bitcast %struct.D5* %{{.*}} to [3 x double]*
+// ARM64: store [3 x double] %x.coerce, [3 x double]*
+
+void call_D5(D5 *p) {
+ func_D5(*p);
+}
+
+// Check the call site.
+//
+// ARM64-LABEL: define void @_Z7call_D5P2D5(%struct.D5* %p)
+// ARM64: load [3 x double], [3 x double]*
+// ARM64: call %struct.D5 @_Z7func_D52D5([3 x double] %{{.*}})
+
+struct Empty { };
+struct Float1 { float x; };
+struct Float2 { float y; };
+struct HVAWithEmptyBase : Float1, Empty, Float2 { float z; };
+
+// PPC: define void @_Z15with_empty_base16HVAWithEmptyBase([3 x float] %a.coerce)
+// ARM64: define void @_Z15with_empty_base16HVAWithEmptyBase([3 x float] %a.coerce)
+// ARM32: define arm_aapcs_vfpcc void @_Z15with_empty_base16HVAWithEmptyBase(%struct.HVAWithEmptyBase %a.coerce)
+void CC with_empty_base(HVAWithEmptyBase a) {}
+
+// FIXME: MSVC doesn't consider this an HVA because of the empty base.
+// X64: define dso_local x86_vectorcallcc void @"\01_Z15with_empty_base16HVAWithEmptyBase@@16"(%struct.HVAWithEmptyBase inreg %a.coerce)
+
+struct HVAWithEmptyBitField : Float1, Float2 {
+ int : 0; // Takes no space.
+ float z;
+};
+
+// PPC: define void @_Z19with_empty_bitfield20HVAWithEmptyBitField([3 x float] %a.coerce)
+// ARM64: define void @_Z19with_empty_bitfield20HVAWithEmptyBitField([3 x float] %a.coerce)
+// ARM32: define arm_aapcs_vfpcc void @_Z19with_empty_bitfield20HVAWithEmptyBitField(%struct.HVAWithEmptyBitField %a.coerce)
+// X64: define dso_local x86_vectorcallcc void @"\01_Z19with_empty_bitfield20HVAWithEmptyBitField@@16"(%struct.HVAWithEmptyBitField inreg %a.coerce)
+void CC with_empty_bitfield(HVAWithEmptyBitField a) {}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/implicit-copy-assign-operator.cpp b/src/llvm-project/clang/test/CodeGenCXX/implicit-copy-assign-operator.cpp
new file mode 100644
index 0000000..fded035
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/implicit-copy-assign-operator.cpp
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -emit-llvm -triple x86_64-apple-darwin10.0.0 -o - %s | FileCheck %s
+struct A {
+ A &operator=(const A&);
+ A &operator=(A&);
+};
+
+struct B {
+ B &operator=(B&);
+};
+
+struct C {
+ virtual C& operator=(const C&);
+};
+
+struct POD {
+ int array[3][4];
+};
+
+struct CopyByValue {
+ CopyByValue(const CopyByValue&);
+ CopyByValue &operator=(CopyByValue);
+};
+
+struct D : A, B, virtual C {
+ int scalar;
+ int scalar_array[2][3];
+ B class_member;
+ C class_member_array[2][3];
+ POD pod_array[2][3];
+
+ union {
+ int x;
+ float f[3];
+ };
+
+ CopyByValue by_value;
+};
+
+void test_D(D d1, D d2) {
+ d1 = d2;
+}
+
+// CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.D* @_ZN1DaSERS_
+// CHECK: {{call.*_ZN1AaSERS_}}
+// CHECK: {{call.*_ZN1BaSERS_}}
+// CHECK: {{call.*_ZN1CaSERKS_}}
+// CHECK: {{call void @llvm.memcpy.p0i8.p0i8.i64.*i64 28}}
+// CHECK: {{call.*_ZN1BaSERS_}}
+// CHECK: br
+// CHECK: {{call.*_ZN1CaSERKS_}}
+// CHECK: {{call void @llvm.memcpy.p0i8.p0i8.i64.*i64 288}}
+// CHECK: {{call void @llvm.memcpy.p0i8.p0i8.i64.*i64 12}}
+// CHECK: call void @_ZN11CopyByValueC1ERKS_
+// CHECK: {{call.*_ZN11CopyByValueaSES_}}
+// CHECK: ret
diff --git a/src/llvm-project/clang/test/CodeGenCXX/implicit-copy-constructor.cpp b/src/llvm-project/clang/test/CodeGenCXX/implicit-copy-constructor.cpp
new file mode 100644
index 0000000..3f8665a
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/implicit-copy-constructor.cpp
@@ -0,0 +1,109 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -std=c++11 | FileCheck %s
+
+struct A {
+ A();
+ A(const A&);
+ A(A&);
+ ~A();
+};
+
+struct B {
+ B();
+ B(B&);
+};
+
+struct C {
+ C() {}
+ C(C& other, A a = A());
+ int i, j;
+};
+
+struct POD {
+ int array[3][4];
+};
+
+struct D : A, B, virtual C {
+ D();
+ int scalar;
+ int scalar_array[2][3];
+ B class_member;
+ C class_member_array[2][3];
+ POD pod_array[2][3];
+
+ union {
+ int x;
+ float f[3];
+ };
+};
+
+void f(D d) {
+ D d2(d);
+}
+
+// CHECK-LABEL: define linkonce_odr void @_ZN1DC1ERS_(%struct.D* %this, %struct.D* dereferenceable({{[0-9]+}})) unnamed_addr
+// CHECK: call void @_ZN1AC1Ev
+// CHECK: call void @_ZN1CC2ERS_1A
+// CHECK: call void @_ZN1AD1Ev
+// CHECK: call void @_ZN1AC2ERS_
+// CHECK: call void @_ZN1BC2ERS_
+// CHECK: {{call void @llvm.memcpy.p0i8.p0i8.i64.*i64 28}}
+// CHECK: call void @_ZN1BC1ERS_
+// CHECK: br label
+// CHECK: call void @_ZN1AC1Ev
+// CHECK: call void @_ZN1CC1ERS_1A
+// CHECK: call void @_ZN1AD1Ev
+// CHECK: {{icmp eq.*, 3}}
+// CHECK: br i1
+// CHECK: {{icmp eq.*, 2}}
+// CHECK: br i1
+// CHECK: {{call void @llvm.memcpy.p0i8.p0i8.i64.*i64 300}}
+// CHECK: ret void
+
+
+template<class T> struct X0 { void f0(T * ) { } };
+template <class > struct X1 { X1( X1& , int = 0 ) { } };
+struct X2 { X1<int> result; };
+void test_X2()
+{
+ typedef X2 impl;
+ typedef X0<impl> pimpl;
+ impl* i;
+ pimpl pdata;
+ pdata.f0( new impl(*i));
+}
+
+// rdar://problem/9598341
+namespace test3 {
+ struct A { A(const A&); A&operator=(const A&); };
+ struct B { A a; unsigned : 0; };
+ void test(const B &x) {
+ B y = x;
+ y = x;
+ }
+}
+
+namespace test4 {
+ // When determining whether to implement an array copy as a memcpy, look at
+ // whether the *selected* constructor is trivial.
+ struct S {
+ int arr[5][5];
+ S(S &);
+ S(const S &) = default;
+ };
+ // CHECK: @_ZN5test42f1
+ void f1(S a) {
+ // CHECK-NOT: memcpy
+ // CHECK: call void @_ZN5test41SC1ERS0_
+ // CHECK-NOT: memcpy
+ S b(a);
+ // CHECK: }
+ }
+ // CHECK: @_ZN5test42f2
+ void f2(const S a) {
+ // CHECK-NOT: call void @_ZN5test41SC1ERS0_
+ // CHECK: memcpy
+ // CHECK-NOT: call void @_ZN5test41SC1ERS0_
+ S b(a);
+ // CHECK: }
+ }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/implicit-exception-spec.cpp b/src/llvm-project/clang/test/CodeGenCXX/implicit-exception-spec.cpp
new file mode 100644
index 0000000..e1a969a
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/implicit-exception-spec.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -emit-llvm -std=c++11 -o - -fcxx-exceptions -fexceptions | FileCheck %s
+
+struct A {
+ A();
+ A(const A&);
+ A(A&&);
+};
+struct B : virtual A {
+ virtual void f() = 0;
+};
+struct C : B {
+ void f();
+};
+
+// CHECK-DAG: define {{.*}} @_ZN1BC2Ev({{.*}} #[[NOUNWIND:[0-9]*]]
+C c1;
+// CHECK-DAG: define {{.*}} @_ZN1BC2ERKS_({{.*}} #[[NOUNWIND]]
+C c2(c1);
+// CHECK-DAG: define {{.*}} @_ZN1BC2EOS_({{.*}} #[[NOUNWIND]]
+C c3(static_cast<C&&>(c1));
+
+// CHECK-DAG: #[[NOUNWIND]] = {{{.*}} nounwind
diff --git a/src/llvm-project/clang/test/CodeGenCXX/implicit-instantiation-1.cpp b/src/llvm-project/clang/test/CodeGenCXX/implicit-instantiation-1.cpp
new file mode 100644
index 0000000..c3c49c3
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/implicit-instantiation-1.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple %s -o %t
+
+template<typename T>
+struct X {
+ void f(T) { }
+ void f(char) { }
+
+ void g(T) { }
+
+ void h(T) { }
+};
+
+void foo(X<int> &xi, X<float> *xfp, int i, float f) {
+ // RUN: grep "linkonce_odr.*_ZN1XIiE1fEi" %t | count 1
+ xi.f(i);
+
+ // RUN: grep "linkonce_odr.*_ZN1XIiE1gEi" %t | count 1
+ xi.g(f);
+
+ // RUN: grep "linkonce_odr.*_ZN1XIfE1fEf" %t | count 1
+ xfp->f(f);
+
+ // RUN: not grep "linkonce_odr.*_ZN1XIfE1hEf" %t
+
+}
+
+
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/implicit-record-visibility.cpp b/src/llvm-project/clang/test/CodeGenCXX/implicit-record-visibility.cpp
new file mode 100644
index 0000000..701a203
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/implicit-record-visibility.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 %s -I%S -fvisibility hidden -triple x86_64-linux-gnu -emit-llvm -o - | FileCheck %s
+
+#include <stdarg.h>
+#include <typeinfo>
+
+// If struct __va_list_tag did not explicitly have default visibility, then
+// under -fvisibility hidden the type of function f, due to its va_list (aka
+// __builtin_va_list, aka __va_list_tag (*)[1]) parameter would be hidden:
+
+// CHECK: @_ZTSFvP13__va_list_tagE = linkonce_odr constant
+// CHECK: @_ZTIFvP13__va_list_tagE = linkonce_odr constant
+void f(va_list) { (void)typeid(f); }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/inalloca-lambda.cpp b/src/llvm-project/clang/test/CodeGenCXX/inalloca-lambda.cpp
new file mode 100644
index 0000000..ac85ee1
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/inalloca-lambda.cpp
@@ -0,0 +1,11 @@
+// RUN: not %clang_cc1 -triple i686-windows-msvc -emit-llvm -o /dev/null %s 2>&1 | FileCheck %s
+
+// PR28299
+// CHECK: error: cannot compile this forwarded non-trivially copyable parameter yet
+
+class A {
+ A(const A &);
+};
+typedef void (*fptr_t)(A);
+fptr_t fn1() { return [](A) {}; }
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/incomplete-member-function-pointer.cpp b/src/llvm-project/clang/test/CodeGenCXX/incomplete-member-function-pointer.cpp
new file mode 100644
index 0000000..b97e44c
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/incomplete-member-function-pointer.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 %s -emit-llvm-only
+// PR7040
+struct fake_tuple;
+struct connection {
+ void bar(fake_tuple);
+};
+void (connection::*a)(fake_tuple) = &connection::bar;
+void f() {
+ void (connection::*b)(fake_tuple) = &connection::bar;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/incomplete-types.cpp b/src/llvm-project/clang/test/CodeGenCXX/incomplete-types.cpp
new file mode 100644
index 0000000..802ed46
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/incomplete-types.cpp
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 %s -emit-llvm-only -verify
+// expected-no-diagnostics
+// PR5489
+
+template<typename E>
+struct Bar {
+ int x_;
+};
+
+static struct Bar<int> bar[1] = {
+ { 0 }
+};
+
+
+
+namespace incomplete_type_refs {
+ struct A;
+ extern A g[];
+ void foo(A*);
+ void f(void) {
+ foo(g); // Reference to array with unknown element type.
+ }
+
+ struct A { // define the element type.
+ int a,b,c;
+ };
+
+ A *f2() {
+ return &g[1];
+ }
+
+}
+
+namespace PR10395 {
+ struct T;
+ extern T x[];
+ T* f() { return x; }
+}
+
+namespace PR10384 {
+ struct X;
+ extern X x[1];
+ X* f() { return x; }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/inheriting-constructor-cleanup.cpp b/src/llvm-project/clang/test/CodeGenCXX/inheriting-constructor-cleanup.cpp
new file mode 100644
index 0000000..3aac9ac
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/inheriting-constructor-cleanup.cpp
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -triple x86_64-darwin -std=c++11 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-darwin -std=c++11 -fcxx-exceptions -fexceptions -emit-llvm -o - %s | FileCheck %s --check-prefix=EXCEPTIONS
+
+// PR36748
+// rdar://problem/45805151
+
+// Classes to verify order of destroying function parameters.
+struct S1 {
+ ~S1();
+};
+struct S2 {
+ ~S2();
+};
+
+struct Base {
+ // Use variadic args to cause inlining the inherited constructor.
+ Base(const S1&, const S2&, const char *fmt, ...) {}
+};
+
+struct NonTrivialDtor {
+ ~NonTrivialDtor() {}
+};
+struct Inheritor : public NonTrivialDtor, public Base {
+ using Base::Base;
+};
+
+void f() {
+ Inheritor(S1(), S2(), "foo");
+ // CHECK-LABEL: define void @_Z1fv
+ // CHECK: %[[TMP1:.*]] = alloca %struct.S1
+ // CHECK: %[[TMP2:.*]] = alloca %struct.S2
+ // CHECK: call void (%struct.Base*, %struct.S1*, %struct.S2*, i8*, ...) @_ZN4BaseC2ERK2S1RK2S2PKcz(%struct.Base* {{.*}}, %struct.S1* dereferenceable(1) %[[TMP1]], %struct.S2* dereferenceable(1) %[[TMP2]], i8* {{.*}})
+ // CHECK-NEXT: call void @_ZN9InheritorD1Ev(%struct.Inheritor* {{.*}})
+ // CHECK-NEXT: call void @_ZN2S2D1Ev(%struct.S2* %[[TMP2]])
+ // CHECK-NEXT: call void @_ZN2S1D1Ev(%struct.S1* %[[TMP1]])
+
+ // EXCEPTIONS-LABEL: define void @_Z1fv
+ // EXCEPTIONS: %[[TMP1:.*]] = alloca %struct.S1
+ // EXCEPTIONS: %[[TMP2:.*]] = alloca %struct.S2
+ // EXCEPTIONS: invoke void (%struct.Base*, %struct.S1*, %struct.S2*, i8*, ...) @_ZN4BaseC2ERK2S1RK2S2PKcz(%struct.Base* {{.*}}, %struct.S1* dereferenceable(1) %[[TMP1]], %struct.S2* dereferenceable(1) %[[TMP2]], i8* {{.*}})
+ // EXCEPTIONS-NEXT: to label %[[CONT:.*]] unwind label %[[LPAD:.*]]
+
+ // EXCEPTIONS: [[CONT]]:
+ // EXCEPTIONS-NEXT: call void @_ZN9InheritorD1Ev(%struct.Inheritor* {{.*}})
+ // EXCEPTIONS-NEXT: call void @_ZN2S2D1Ev(%struct.S2* %[[TMP2]])
+ // EXCEPTIONS-NEXT: call void @_ZN2S1D1Ev(%struct.S1* %[[TMP1]])
+
+ // EXCEPTIONS: [[LPAD]]:
+ // EXCEPTIONS: call void @_ZN14NonTrivialDtorD2Ev(%struct.NonTrivialDtor* {{.*}})
+ // EXCEPTIONS-NEXT: call void @_ZN2S2D1Ev(%struct.S2* %[[TMP2]])
+ // EXCEPTIONS-NEXT: call void @_ZN2S1D1Ev(%struct.S1* %[[TMP1]])
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/inheriting-constructor.cpp b/src/llvm-project/clang/test/CodeGenCXX/inheriting-constructor.cpp
new file mode 100644
index 0000000..fa3e5ab
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/inheriting-constructor.cpp
@@ -0,0 +1,410 @@
+// RUN: %clang_cc1 -std=c++11 -triple i386-linux -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=ITANIUM
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-darwin -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=ITANIUM
+// RUN: %clang_cc1 -std=c++11 -triple arm64-ehabi -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=ITANIUM
+// RUN: %clang_cc1 -std=c++11 -triple i386-windows -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=MSABI --check-prefix=WIN32
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=MSABI --check-prefix=WIN64
+
+// PR12219
+struct A { A(int); virtual ~A(); };
+struct B : A { using A::A; ~B(); };
+B::~B() {}
+
+B b(123);
+
+struct C { template<typename T> C(T); };
+struct D : C { using C::C; };
+D d(123);
+
+// ITANIUM-LABEL: define void @_ZN1BD2Ev
+// ITANIUM-LABEL: define void @_ZN1BD1Ev
+// ITANIUM-LABEL: define void @_ZN1BD0Ev
+// WIN32-LABEL: define {{.*}}void @"??1B@@UAE@XZ"
+// WIN64-LABEL: define {{.*}}void @"??1B@@UEAA@XZ"
+
+// ITANIUM-LABEL: define linkonce_odr void @_ZN1BCI11AEi(
+// ITANIUM: call void @_ZN1BCI21AEi(
+
+// ITANIUM-LABEL: define linkonce_odr void @_ZN1DCI11CIiEET_(
+// ITANIUM: call void @_ZN1DCI21CIiEET_(
+
+// WIN32-LABEL: define internal {{.*}} @"??0B@@QAE@H@Z"(
+// WIN32: call {{.*}} @"??0A@@QAE@H@Z"(
+// WIN64-LABEL: define internal {{.*}} @"??0B@@QEAA@H@Z"(
+// WIN64: call {{.*}} @"??0A@@QEAA@H@Z"(
+
+// WIN32-LABEL: define internal {{.*}} @"??0D@@QAE@H@Z"(
+// WIN32: call {{.*}} @"??$?0H@C@@QAE@H@Z"
+// WIN64-LABEL: define internal {{.*}} @"??0D@@QEAA@H@Z"(
+// WIN64: call {{.*}} @"??$?0H@C@@QEAA@H@Z"
+
+struct Q { Q(int); Q(const Q&); ~Q(); };
+struct Z { Z(); Z(int); ~Z(); int n; };
+
+namespace noninline_nonvirt {
+ struct A { A(int, Q&&, void *__attribute__((pass_object_size(0)))); int n; };
+ struct B : Z, A { Z z; using A::A; };
+ B b(1, 2, &b);
+ // ITANIUM-LABEL: define {{.*}} @__cxx_global_var_init
+ // ITANIUM: call void @_ZN1QC1Ei({{.*}} %[[TMP:.*]], i32 2)
+ // ITANIUM: call void @_ZN17noninline_nonvirt1BCI1NS_1AEEiO1QPvU17pass_object_size0({{.*}} @_ZN17noninline_nonvirt1bE, i32 1, {{.*}} %[[TMP]], i8* {{.*}} @_ZN17noninline_nonvirt1bE{{.*}}, i{{32|64}} 12)
+ // ITANIUM: call void @_ZN1QD1Ev({{.*}} %[[TMP]])
+ // ITANIUM: call i32 @__cxa_atexit(
+
+ // Complete object ctor for B delegates to base object ctor.
+ // ITANIUM-LABEL: define linkonce_odr void @_ZN17noninline_nonvirt1BCI1NS_1AEEiO1QPvU17pass_object_size0(
+ // ITANIUM: call void @_ZN17noninline_nonvirt1BCI2NS_1AEEiO1QPvU17pass_object_size0({{.*}}, i32 {{.*}}, %{{.*}}* {{.*}}, i8* {{.*}}, i{{32|64}} {{.*}})
+
+ // In MSABI, we don't have ctor variants. B ctor forwards to A ctor.
+ // MSABI-LABEL: define internal {{.*}} @"??0B@noninline_nonvirt@@Q{{AE|EAA}}@H$$Q{{E?}}AUQ@@P{{E?}}AXW4__pass_object_size0@__clang@@@Z"(%{{.*}}, i32{{.*}}, %{{.*}}, i8*{{.*}}, i{{32|64}}{{.*}})
+ // MSABI: call {{.*}} @"??0Z@@Q{{AE|EAA}}@XZ"(
+ // MSABI: call {{.*}} @"??0A@noninline_nonvirt@@Q{{AE|EAA}}@H$$Q{{E?}}AUQ@@P{{E?}}AXW4__pass_object_size0@__clang@@@Z"(%{{.*}}, i32{{.*}}, %{{.*}}, i8*{{.*}}, i{{32|64}}{{.*}})
+ // MSABI: call {{.*}} @"??0Z@@Q{{AE|EAA}}@XZ"(
+
+ struct C : B { using B::B; };
+ C c(1, 2, &c);
+ // Complete object ctor for C delegates.
+ // ITANIUM-LABEL: define linkonce_odr void @_ZN17noninline_nonvirt1CCI1NS_1AEEiO1QPvU17pass_object_size0(
+ // ITANIUM: call void @_ZN17noninline_nonvirt1CCI2NS_1AEEiO1QPvU17pass_object_size0({{.*}}, i32 {{.*}}, %{{.*}}* {{.*}}, i8* {{.*}}, i{{32|64}} {{.*}})
+
+ // MSABI-LABEL: define internal {{.*}} @"??0C@noninline_nonvirt@@Q{{AE|EAA}}@H$$Q{{E?}}AUQ@@P{{E?}}AXW4__pass_object_size0@__clang@@@Z"(%{{.*}}, i32{{.*}}, %{{.*}}, i8*{{.*}}, i{{32|64}}{{.*}})
+ // MSABI: call {{.*}} @"??0B@noninline_nonvirt@@Q{{AE|EAA}}@H$$Q{{E?}}AUQ@@P{{E?}}AXW4__pass_object_size0@__clang@@@Z"(%{{.*}}, i32{{.*}}, %{{.*}}, i8*{{.*}}, i{{32|64}}{{.*}})
+}
+
+namespace noninline_virt {
+ struct A { A(int, Q&&, void *__attribute__((pass_object_size(0)))); int n; };
+ struct B : Z, virtual A { Z z; using A::A; };
+ B b(1, 2, &b);
+ // Complete object ctor forwards to A ctor then constructs Zs.
+ // ITANIUM-LABEL: define linkonce_odr void @_ZN14noninline_virt1BCI1NS_1AEEiO1QPvU17pass_object_size0(
+ // ITANIUM: call void @_ZN14noninline_virt1AC2EiO1QPvU17pass_object_size0({{.*}} %{{.*}}, i32 %{{.*}}, %{{.*}}* {{.*}}, i8* {{.*}}, i{{32|64}} %{{.*}}
+ // ITANIUM: call void @_ZN1ZC2Ev(
+ // ITANIUM: store {{.*}} @_ZTVN14noninline_virt1BE
+ // ITANIUM: call void @_ZN1ZC1Ev(
+
+ // MSABI-LABEL: define internal {{.*}} @"??0B@noninline_virt@@Q{{AE|EAA}}@H$$Q{{E?}}AUQ@@P{{E?}}AXW4__pass_object_size0@__clang@@@Z"(%{{.*}}, i32{{.*}}, %{{.*}}, i8*{{.*}}, i{{32|64}}{{.*}}, i32 %{{.*}})
+ // MSABI: %[[COMPLETE:.*]] = icmp ne
+ // MSABI: br i1 %[[COMPLETE]],
+ // MSABI: call {{.*}} @"??0A@noninline_virt@@Q{{AE|EAA}}@H$$Q{{E?}}AUQ@@P{{E?}}AXW4__pass_object_size0@__clang@@@Z"(%{{.*}}, i32{{.*}}, %{{.*}}, i8*{{.*}}, i{{32|64}}{{.*}})
+ // MSABI: br
+ // MSABI: call {{.*}} @"??0Z@@Q{{AE|EAA}}@XZ"(
+ // MSABI: call {{.*}} @"??0Z@@Q{{AE|EAA}}@XZ"(
+
+ struct C : B { using B::B; };
+ C c(1, 2, &c);
+ // Complete object ctor forwards to A ctor, then calls B's base inheriting
+ // constructor, which takes no arguments other than the this pointer and VTT.
+ // ITANIUM_LABEL: define linkonce_odr void @_ZN14noninline_virt1CCI1NS_1AEEiO1QPvU17pass_object_size0(
+ // ITANIUM: call void @_ZN14noninline_virt1AC2EiO1QPvU17pass_object_size0({{.*}} %{{.*}}, i32 %{{.*}}, %{{.*}}* {{.*}}, i8* %{{.*}}, i{{32|64}} %{{.*}})
+ // ITANIUM: call void @_ZN14noninline_virt1BCI2NS_1AEEiO1QPvU17pass_object_size0(%{{.*}}* %{{.*}}, i8** getelementptr inbounds ([2 x i8*], [2 x i8*]* @_ZTTN14noninline_virt1CE, i64 0, i64 1))
+ // ITANIUM: store {{.*}} @_ZTVN14noninline_virt1CE
+
+ // C constructor forwards to B constructor and A constructor. We pass the args
+ // to both. FIXME: Can we pass undef here instead, for the base object
+ // constructor call?
+ // MSABI-LABEL: define internal {{.*}} @"??0C@noninline_virt@@Q{{AE|EAA}}@H$$Q{{E?}}AUQ@@P{{E?}}AXW4__pass_object_size0@__clang@@@Z"(%{{.*}}, i32{{.*}}, %{{.*}}, i8*{{.*}}, i{{32|64}}{{.*}}, i32 %{{.*}})
+ // MSABI: %[[COMPLETE:.*]] = icmp ne
+ // MSABI: br i1 %[[COMPLETE]],
+ // MSABI: call {{.*}} @"??0A@noninline_virt@@Q{{AE|EAA}}@H$$Q{{E?}}AUQ@@P{{E?}}AXW4__pass_object_size0@__clang@@@Z"(%{{.*}}, i32{{.*}}, %{{.*}}, i8*{{.*}}, i{{32|64}}{{.*}})
+ // MSABI: br
+ // MSABI: call {{.*}} @"??0B@noninline_virt@@Q{{AE|EAA}}@H$$Q{{E?}}AUQ@@P{{E?}}AXW4__pass_object_size0@__clang@@@Z"(%{{.*}}, i32{{.*}}, %{{.*}}, i8*{{.*}}, i{{32|64}}{{.*}}, i32 0)
+}
+
+// For MSABI only, check that inalloca arguments result in inlining.
+namespace inalloca_nonvirt {
+ struct A { A(Q, int, Q, Q&&); int n; };
+ struct B : Z, A { Z z; using A::A; };
+ B b(1, 2, 3, 4);
+ // No inlining implied for Itanium.
+ // ITANIUM-LABEL: define linkonce_odr void @_ZN16inalloca_nonvirt1BCI1NS_1AEE1QiS1_OS1_(
+ // ITANIUM: call void @_ZN16inalloca_nonvirt1BCI2NS_1AEE1QiS1_OS1_(
+
+ // MSABI-LABEL: define internal void @"??__Eb@inalloca_nonvirt@@YAXXZ"(
+
+ // On Win32, the inalloca call can't be forwarded so we force inlining.
+ // WIN32: %[[TMP:.*]] = alloca
+ // WIN32: call i8* @llvm.stacksave()
+ // WIN32: %[[ARGMEM:.*]] = alloca inalloca
+ // WIN32: call {{.*}} @"??0Q@@QAE@H@Z"(%{{.*}}* %[[TMP]], i32 4)
+ // WIN32: %[[ARG3:.*]] = getelementptr {{.*}} %[[ARGMEM]]
+ // WIN32: call {{.*}} @"??0Q@@QAE@H@Z"({{.*}}* %[[ARG3]], i32 3)
+ // WIN32: %[[ARG1:.*]] = getelementptr {{.*}} %[[ARGMEM]]
+ // WIN32: call {{.*}} @"??0Q@@QAE@H@Z"({{.*}}* %[[ARG1]], i32 1)
+ // WIN32: call {{.*}} @"??0Z@@QAE@XZ"(
+ // WIN32: %[[ARG2:.*]] = getelementptr {{.*}} %[[ARGMEM]]
+ // WIN32: store i32 2, i32* %[[ARG2]]
+ // WIN32: %[[ARG4:.*]] = getelementptr {{.*}} %[[ARGMEM]]
+ // WIN32: store {{.*}}* %[[TMP]], {{.*}}** %[[ARG4]]
+ // WIN32: call {{.*}} @"??0A@inalloca_nonvirt@@QAE@UQ@@H0$$QAU2@@Z"(%{{[^,]*}}, <{{.*}}>* inalloca %[[ARGMEM]])
+ // WIN32: call void @llvm.stackrestore(
+ // WIN32: call {{.*}} @"??0Z@@QAE@XZ"(
+ // WIN32: call {{.*}} @"??1Q@@QAE@XZ"(
+
+ // On Win64, the Q arguments would be destroyed in the callee. We don't yet
+ // support that in the non-inlined case, so we force inlining.
+ // WIN64: %[[TMP:.*]] = alloca
+ // WIN64: %[[ARG3:.*]] = alloca
+ // WIN64: %[[ARG1:.*]] = alloca
+ // WIN64: call {{.*}} @"??0Q@@QEAA@H@Z"({{.*}}* %[[TMP]], i32 4)
+ // WIN64: call {{.*}} @"??0Q@@QEAA@H@Z"({{.*}}* %[[ARG3]], i32 3)
+ // WIN64: call {{.*}} @"??0Q@@QEAA@H@Z"({{.*}}* %[[ARG1]], i32 1)
+ // WIN64: call {{.*}} @"??0Z@@QEAA@XZ"(
+ // WIN64: call {{.*}} @"??0A@inalloca_nonvirt@@QEAA@UQ@@H0$$QEAU2@@Z"(%{{.*}}, %{{.*}}* %[[ARG1]], i32 2, %{{.*}}* %[[ARG3]], %{{.*}} %[[TMP]])
+ // WIN64: call {{.*}} @"??0Z@@QEAA@XZ"(
+ // WIN64: call void @"??1Q@@QEAA@XZ"({{.*}}* %[[TMP]])
+
+ struct C : B { using B::B; };
+ C c(1, 2, 3, 4);
+ // MSABI-LABEL: define internal void @"??__Ec@inalloca_nonvirt@@YAXXZ"(
+
+ // On Win32, the inalloca call can't be forwarded so we force inlining.
+ // WIN32: %[[TMP:.*]] = alloca
+ // WIN32: call i8* @llvm.stacksave()
+ // WIN32: %[[ARGMEM:.*]] = alloca inalloca
+ // WIN32: call {{.*}} @"??0Q@@QAE@H@Z"(%{{.*}}* %[[TMP]], i32 4)
+ // WIN32: %[[ARG3:.*]] = getelementptr {{.*}} %[[ARGMEM]]
+ // WIN32: call {{.*}} @"??0Q@@QAE@H@Z"({{.*}}* %[[ARG3]], i32 3)
+ // WIN32: %[[ARG1:.*]] = getelementptr {{.*}} %[[ARGMEM]]
+ // WIN32: call {{.*}} @"??0Q@@QAE@H@Z"({{.*}}* %[[ARG1]], i32 1)
+ // WIN32: call {{.*}} @"??0Z@@QAE@XZ"(
+ // WIN32: %[[ARG2:.*]] = getelementptr {{.*}} %[[ARGMEM]]
+ // WIN32: store i32 2, i32* %[[ARG2]]
+ // WIN32: %[[ARG4:.*]] = getelementptr {{.*}} %[[ARGMEM]]
+ // WIN32: store {{.*}}* %[[TMP]], {{.*}}** %[[ARG4]]
+ // WIN32: call {{.*}} @"??0A@inalloca_nonvirt@@QAE@UQ@@H0$$QAU2@@Z"(%{{[^,]*}}, <{{.*}}>* inalloca %[[ARGMEM]])
+ // WIN32: call void @llvm.stackrestore(
+ // WIN32: call {{.*}} @"??0Z@@QAE@XZ"(
+ // WIN32: call {{.*}} @"??1Q@@QAE@XZ"(
+
+ // On Win64, the Q arguments would be destroyed in the callee. We don't yet
+ // support that in the non-inlined case, so we force inlining.
+ // WIN64: %[[TMP:.*]] = alloca
+ // WIN64: %[[ARG3:.*]] = alloca
+ // WIN64: %[[ARG1:.*]] = alloca
+ // WIN64: call {{.*}} @"??0Q@@QEAA@H@Z"({{.*}}* %[[TMP]], i32 4)
+ // WIN64: call {{.*}} @"??0Q@@QEAA@H@Z"({{.*}}* %[[ARG3]], i32 3)
+ // WIN64: call {{.*}} @"??0Q@@QEAA@H@Z"({{.*}}* %[[ARG1]], i32 1)
+ // WIN64: call {{.*}} @"??0Z@@QEAA@XZ"(
+ // WIN64: call {{.*}} @"??0A@inalloca_nonvirt@@QEAA@UQ@@H0$$QEAU2@@Z"(%{{.*}}, %{{.*}}* %[[ARG1]], i32 2, %{{.*}}* %[[ARG3]], %{{.*}} %[[TMP]])
+ // WIN64: call {{.*}} @"??0Z@@QEAA@XZ"(
+ // WIN64: call void @"??1Q@@QEAA@XZ"({{.*}}* %[[TMP]])
+}
+
+namespace inalloca_virt {
+ struct A { A(Q, int, Q, Q&&); int n; };
+ struct B : Z, virtual A { Z z; using A::A; };
+ B b(1, 2, 3, 4);
+
+ // MSABI-LABEL: define internal void @"??__Eb@inalloca_virt@@YAXXZ"(
+
+ // On Win32, the inalloca call can't be forwarded so we force inlining.
+ // WIN32: %[[TMP:.*]] = alloca
+ // WIN32: call i8* @llvm.stacksave()
+ // WIN32: %[[ARGMEM:.*]] = alloca inalloca
+ // WIN32: call {{.*}} @"??0Q@@QAE@H@Z"(%{{.*}}* %[[TMP]], i32 4)
+ // WIN32: %[[ARG3:.*]] = getelementptr {{.*}} %[[ARGMEM]]
+ // WIN32: call {{.*}} @"??0Q@@QAE@H@Z"({{.*}}* %[[ARG3]], i32 3)
+ // WIN32: %[[ARG1:.*]] = getelementptr {{.*}} %[[ARGMEM]]
+ // WIN32: call {{.*}} @"??0Q@@QAE@H@Z"({{.*}}* %[[ARG1]], i32 1)
+ // FIXME: It's dumb to round-trip this though memory and generate a branch.
+ // WIN32: store i32 1, i32* %[[IS_MOST_DERIVED_ADDR:.*]]
+ // WIN32: %[[IS_MOST_DERIVED:.*]] = load i32, i32* %[[IS_MOST_DERIVED_ADDR]]
+ // WIN32: %[[IS_MOST_DERIVED_i1:.*]] = icmp ne i32 %[[IS_MOST_DERIVED]], 0
+ // WIN32: br i1 %[[IS_MOST_DERIVED_i1]]
+ //
+ // WIN32: store {{.*}} @"??_8B@inalloca_virt@@7B@"
+ // WIN32: %[[ARG2:.*]] = getelementptr {{.*}} %[[ARGMEM]]
+ // WIN32: store i32 2, i32* %[[ARG2]]
+ // WIN32: %[[ARG4:.*]] = getelementptr {{.*}} %[[ARGMEM]]
+ // WIN32: store {{.*}}* %[[TMP]], {{.*}}** %[[ARG4]]
+ // WIN32: call {{.*}} @"??0A@inalloca_virt@@QAE@UQ@@H0$$QAU2@@Z"(%{{[^,]*}}, <{{.*}}>* inalloca %[[ARGMEM]])
+ // WIN32: call void @llvm.stackrestore(
+ // WIN32: br
+ //
+ // Note that if we jumped directly to here we would fail to stackrestore and
+ // destroy the parameters, but that's not actually possible.
+ // WIN32: call {{.*}} @"??0Z@@QAE@XZ"(
+ // WIN32: call {{.*}} @"??0Z@@QAE@XZ"(
+ // WIN32: call {{.*}} @"??1Q@@QAE@XZ"(
+
+ // On Win64, the Q arguments would be destroyed in the callee. We don't yet
+ // support that in the non-inlined case, so we force inlining.
+ // WIN64: %[[TMP:.*]] = alloca
+ // WIN64: %[[ARG3:.*]] = alloca
+ // WIN64: %[[ARG1:.*]] = alloca
+ // WIN64: call {{.*}} @"??0Q@@QEAA@H@Z"({{.*}}* %[[TMP]], i32 4)
+ // WIN64: call {{.*}} @"??0Q@@QEAA@H@Z"({{.*}}* %[[ARG3]], i32 3)
+ // WIN64: call {{.*}} @"??0Q@@QEAA@H@Z"({{.*}}* %[[ARG1]], i32 1)
+ // WIN64: br i1
+ // WIN64: call {{.*}} @"??0A@inalloca_virt@@QEAA@UQ@@H0$$QEAU2@@Z"(%{{.*}}, %{{.*}}* %[[ARG1]], i32 2, %{{.*}}* %[[ARG3]], %{{.*}} %[[TMP]])
+ // WIN64: br
+ // WIN64: call {{.*}} @"??0Z@@QEAA@XZ"(
+ // WIN64: call {{.*}} @"??0Z@@QEAA@XZ"(
+ // WIN64: call void @"??1Q@@QEAA@XZ"({{.*}}* %[[TMP]])
+
+ struct C : B { using B::B; };
+ C c(1, 2, 3, 4);
+ // ITANIUM-LABEL: define linkonce_odr void @_ZN13inalloca_virt1CD1Ev(
+
+ // MSABI-LABEL: define internal void @"??__Ec@inalloca_virt@@YAXXZ"(
+
+ // On Win32, the inalloca call can't be forwarded so we force inlining.
+ // WIN32: %[[TMP:.*]] = alloca
+ // WIN32: call i8* @llvm.stacksave()
+ // WIN32: %[[ARGMEM:.*]] = alloca inalloca
+ // WIN32: call {{.*}} @"??0Q@@QAE@H@Z"(%{{.*}}* %[[TMP]], i32 4)
+ // WIN32: %[[ARG3:.*]] = getelementptr {{.*}} %[[ARGMEM]]
+ // WIN32: call {{.*}} @"??0Q@@QAE@H@Z"({{.*}}* %[[ARG3]], i32 3)
+ // WIN32: %[[ARG1:.*]] = getelementptr {{.*}} %[[ARGMEM]]
+ // WIN32: call {{.*}} @"??0Q@@QAE@H@Z"({{.*}}* %[[ARG1]], i32 1)
+ // WIN32: store i32 1, i32* %[[IS_MOST_DERIVED_ADDR:.*]]
+ // WIN32: %[[IS_MOST_DERIVED:.*]] = load i32, i32* %[[IS_MOST_DERIVED_ADDR]]
+ // WIN32: %[[IS_MOST_DERIVED_i1:.*]] = icmp ne i32 %[[IS_MOST_DERIVED]], 0
+ // WIN32: br i1 %[[IS_MOST_DERIVED_i1]]
+ //
+ // WIN32: store {{.*}} @"??_8C@inalloca_virt@@7B@"
+ // WIN32: %[[ARG2:.*]] = getelementptr {{.*}} %[[ARGMEM]]
+ // WIN32: store i32 2, i32* %[[ARG2]]
+ // WIN32: %[[ARG4:.*]] = getelementptr {{.*}} %[[ARGMEM]]
+ // WIN32: store {{.*}}* %[[TMP]], {{.*}}** %[[ARG4]]
+ // WIN32: call {{.*}} @"??0A@inalloca_virt@@QAE@UQ@@H0$$QAU2@@Z"(%{{[^,]*}}, <{{.*}}>* inalloca %[[ARGMEM]])
+ // WIN32: call void @llvm.stackrestore(
+ // WIN32: br
+ //
+ // WIN32: store i32 0, i32* %[[IS_MOST_DERIVED_ADDR:.*]]
+ // WIN32: %[[IS_MOST_DERIVED:.*]] = load i32, i32* %[[IS_MOST_DERIVED_ADDR]]
+ // WIN32: %[[IS_MOST_DERIVED_i1:.*]] = icmp ne i32 %[[IS_MOST_DERIVED]], 0
+ // WIN32: br i1 %[[IS_MOST_DERIVED_i1]]
+ //
+ // Note: this block is unreachable.
+ // WIN32: store {{.*}} @"??_8B@inalloca_virt@@7B@"
+ // WIN32: br
+ //
+ // WIN32: call {{.*}} @"??0Z@@QAE@XZ"(
+ // WIN32: call {{.*}} @"??0Z@@QAE@XZ"(
+ // WIN32: call {{.*}} @"??1Q@@QAE@XZ"(
+
+ // On Win64, the Q arguments would be destroyed in the callee. We don't yet
+ // support that in the non-inlined case, so we force inlining.
+ // WIN64: %[[TMP:.*]] = alloca
+ // WIN64: %[[ARG3:.*]] = alloca
+ // WIN64: %[[ARG1:.*]] = alloca
+ // WIN64: call {{.*}} @"??0Q@@QEAA@H@Z"({{.*}}* %[[TMP]], i32 4)
+ // WIN64: call {{.*}} @"??0Q@@QEAA@H@Z"({{.*}}* %[[ARG3]], i32 3)
+ // WIN64: call {{.*}} @"??0Q@@QEAA@H@Z"({{.*}}* %[[ARG1]], i32 1)
+ // WIN64: br i1
+ // WIN64: store {{.*}} @"??_8C@inalloca_virt@@7B@"
+ // WIN64: call {{.*}} @"??0A@inalloca_virt@@QEAA@UQ@@H0$$QEAU2@@Z"(%{{.*}}, %{{.*}}* %[[ARG1]], i32 2, %{{.*}}* %[[ARG3]], %{{.*}} %[[TMP]])
+ // WIN64: br
+ // WIN64: br i1
+ // (Unreachable block)
+ // WIN64: store {{.*}} @"??_8B@inalloca_virt@@7B@"
+ // WIN64: br
+ // WIN64: call {{.*}} @"??0Z@@QEAA@XZ"(
+ // WIN64: call {{.*}} @"??0Z@@QEAA@XZ"(
+ // WIN64: call void @"??1Q@@QEAA@XZ"({{.*}}* %[[TMP]])
+}
+
+namespace inline_nonvirt {
+ struct A { A(Q, int, Q, Q&&, ...); int n; };
+ struct B : Z, A { Z z; using A::A; };
+ B b(1, 2, 3, 4, 5, 6);
+ // Inlined all the way down to the A ctor.
+ // ITANIUM-LABEL: define {{.*}} @__cxx_global_var_init
+ // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 1)
+ // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 3)
+ // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 4)
+ // ITANIUM: %[[Z_BASE:.*]] = bitcast %{{.*}}* %[[THIS:.*]] to
+ // ITANIUM: call void @_ZN1ZC2Ev(
+ // ITANIUM: %[[B_CAST:.*]] = bitcast {{.*}} %[[THIS]]
+ // ITANIUM: %[[A_CAST:.*]] = getelementptr {{.*}} %[[B_CAST]], i{{32|64}} 4
+ // ITANIUM: %[[A:.*]] = bitcast {{.*}} %[[A_CAST]]
+ // ITANIUM: call void ({{.*}}, ...) @_ZN14inline_nonvirt1AC2E1QiS1_OS1_z(%{{.*}}* %[[A]], {{.*}}, i32 2, {{.*}}, {{.*}}, i32 5, i32 6)
+ // ITANIUM: %[[Z_MEMBER:.*]] = getelementptr {{.*}} %[[THIS]], i32 0, i32 2
+ // ITANIUM: call void @_ZN1ZC1Ev({{.*}} %[[Z_MEMBER]])
+ // ITANIUM: call void @_ZN1QD1Ev(
+ // ITANIUM: call void @_ZN1QD1Ev(
+ // ITANIUM: call void @_ZN1QD1Ev(
+
+ struct C : B { using B::B; };
+ C c(1, 2, 3, 4, 5, 6);
+ // Inlined all the way down to the A ctor.
+ // ITANIUM-LABEL: define {{.*}} @__cxx_global_var_init
+ // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 1)
+ // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 3)
+ // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 4)
+ // ITANIUM: %[[Z_BASE:.*]] = bitcast %{{.*}}* %[[THIS:.*]] to
+ // ITANIUM: call void @_ZN1ZC2Ev(
+ // ITANIUM: %[[B_CAST:.*]] = bitcast {{.*}} %[[THIS]]
+ // ITANIUM: %[[A_CAST:.*]] = getelementptr {{.*}} %[[B_CAST]], i{{32|64}} 4
+ // ITANIUM: %[[A:.*]] = bitcast {{.*}} %[[A_CAST]]
+ // ITANIUM: call void ({{.*}}, ...) @_ZN14inline_nonvirt1AC2E1QiS1_OS1_z(%{{.*}}* %[[A]], {{.*}}, i32 2, {{.*}}, {{.*}}, i32 5, i32 6)
+ // ITANIUM: %[[Z_MEMBER:.*]] = getelementptr {{.*}} %{{.*}}, i32 0, i32 2
+ // ITANIUM: call void @_ZN1ZC1Ev({{.*}} %[[Z_MEMBER]])
+ // ITANIUM: call void @_ZN1QD1Ev(
+ // ITANIUM: call void @_ZN1QD1Ev(
+ // ITANIUM: call void @_ZN1QD1Ev(
+}
+
+namespace inline_virt {
+ struct A { A(Q, int, Q, Q&&, ...); int n; };
+ struct B : Z, virtual A { Z z; using A::A; };
+ B b(1, 2, 3, 4, 5, 6);
+ // Inlined all the way down to the A ctor.
+ // ITANIUM-LABEL: define {{.*}} @__cxx_global_var_init
+ // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 1)
+ // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 3)
+ // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 4)
+ // ITANIUM: %[[B_CAST:.*]] = bitcast {{.*}} %[[THIS:.*]]
+ // ITANIUM: %[[A_CAST:.*]] = getelementptr {{.*}} %[[B_CAST]], i{{32|64}} {{12|16}}
+ // ITANIUM: %[[A:.*]] = bitcast {{.*}} %[[A_CAST]]
+ // ITANIUM: call void ({{.*}}, ...) @_ZN11inline_virt1AC2E1QiS1_OS1_z(%{{.*}}* %[[A]], {{.*}}, i32 2, {{.*}}, {{.*}}, i32 5, i32 6)
+ // ITANIUM: call void @_ZN1ZC2Ev(
+ // ITANIUM: call void @_ZN1ZC1Ev(
+ // ITANIUM: call void @_ZN1QD1Ev(
+ // ITANIUM: call void @_ZN1QD1Ev(
+ // ITANIUM: call void @_ZN1QD1Ev(
+
+ struct C : B { using B::B; };
+ C c(1, 2, 3, 4, 5, 6);
+ // Inlined all the way down to the A ctor, except that we can just call the
+ // B base inheriting constructor to construct that portion (it doesn't need
+ // the forwarded arguments).
+ // ITANIUM-LABEL: define {{.*}} @__cxx_global_var_init
+ // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 1)
+ // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 3)
+ // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 4)
+ // ITANIUM: %[[B_CAST:.*]] = bitcast {{.*}} %[[THIS:.*]]
+ // ITANIUM: %[[A_CAST:.*]] = getelementptr {{.*}} %[[B_CAST]], i{{32|64}} {{12|16}}
+ // ITANIUM: %[[A:.*]] = bitcast {{.*}} %[[A_CAST]]
+ // ITANIUM: call void ({{.*}}, ...) @_ZN11inline_virt1AC2E1QiS1_OS1_z(%{{.*}}* %[[A]], {{.*}}, i32 2, {{.*}}, {{.*}}, i32 5, i32 6)
+ // ITANIUM: call void @_ZN11inline_virt1BCI2NS_1AEE1QiS1_OS1_z({{[^,]*}}, i8** getelementptr inbounds ([2 x i8*], [2 x i8*]* @_ZTTN11inline_virt1CE, i64 0, i64 1))
+ // ITANIUM: store {{.*}} @_ZTVN11inline_virt1CE
+ // ITANIUM: call void @_ZN1QD1Ev(
+ // ITANIUM: call void @_ZN1QD1Ev(
+ // ITANIUM: call void @_ZN1QD1Ev(
+
+ // B base object inheriting constructor does not get passed arguments.
+ // ITANIUM-LABEL: define linkonce_odr void @_ZN11inline_virt1BCI2NS_1AEE1QiS1_OS1_z(
+ // ITANIUM-NOT: call
+ // ITANIUM: call void @_ZN1ZC2Ev(
+ // ITANIUM-NOT: call
+ // VTT -> vtable
+ // ITANIUM: store
+ // ITANIUM-NOT: call
+ // ITANIUM: call void @_ZN1ZC1Ev(
+ // ITANIUM-NOT: call
+ // ITANIUM: }
+}
+
+// ITANIUM-LABEL: define linkonce_odr void @_ZN1BCI21AEi(
+// ITANIUM: call void @_ZN1AC2Ei(
+
+// ITANIUM-LABEL: define linkonce_odr void @_ZN1DCI21CIiEET_(
+// ITANIUM: call void @_ZN1CC2IiEET_(
+
+// ITANIUM-LABEL: define linkonce_odr void @_ZN17noninline_nonvirt1BCI2NS_1AEEiO1QPvU17pass_object_size0(
+// ITANIUM: call void @_ZN1ZC2Ev(
+// ITANIUM: call void @_ZN17noninline_nonvirt1AC2EiO1QPvU17pass_object_size0(
+
+// ITANIUM-LABEL: define linkonce_odr void @_ZN17noninline_nonvirt1CCI2NS_1AEEiO1QPvU17pass_object_size0(
+// ITANIUM: call void @_ZN17noninline_nonvirt1BCI2NS_1AEEiO1QPvU17pass_object_size0(
diff --git a/src/llvm-project/clang/test/CodeGenCXX/init-invariant.cpp b/src/llvm-project/clang/test/CodeGenCXX/init-invariant.cpp
new file mode 100644
index 0000000..815287c
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/init-invariant.cpp
@@ -0,0 +1,60 @@
+// RUN: %clang_cc1 -triple i686-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-O0
+// RUN: %clang_cc1 -triple i686-linux-gnu -emit-llvm %s -O1 -o - | FileCheck %s
+
+// Check that we add an llvm.invariant.start.p0i8 to mark when a global becomes
+// read-only. If globalopt can fold the initializer, it will then mark the
+// variable as constant.
+
+// Do not produce markers at -O0.
+// CHECK-O0-NOT: llvm.invariant.start.p0i8
+
+struct A {
+ A();
+ int n;
+};
+
+// CHECK: @a = global {{.*}} zeroinitializer
+extern const A a = A();
+
+struct B {
+ B();
+ mutable int n;
+};
+
+// CHECK: @b = global {{.*}} zeroinitializer
+extern const B b = B();
+
+struct C {
+ C();
+ ~C();
+ int n;
+};
+
+// CHECK: @c = global {{.*}} zeroinitializer
+extern const C c = C();
+
+int f();
+// CHECK: @d = global i32 0
+extern const int d = f();
+
+void e() {
+ static const A a = A();
+}
+
+// CHECK: call void @_ZN1AC1Ev({{.*}}* nonnull @a)
+// CHECK: call {{.*}}@llvm.invariant.start.p0i8(i64 4, i8* bitcast ({{.*}} @a to i8*))
+
+// CHECK: call void @_ZN1BC1Ev({{.*}}* nonnull @b)
+// CHECK-NOT: call {{.*}}@llvm.invariant.start.p0i8(i64 4, i8* bitcast ({{.*}} @b to i8*))
+
+// CHECK: call void @_ZN1CC1Ev({{.*}}* nonnull @c)
+// CHECK-NOT: call {{.*}}@llvm.invariant.start.p0i8(i64 4, i8* bitcast ({{.*}} @c to i8*))
+
+// CHECK: call i32 @_Z1fv(
+// CHECK: store {{.*}}, i32* @d
+// CHECK: call {{.*}}@llvm.invariant.start.p0i8(i64 4, i8* bitcast ({{.*}} @d to i8*))
+
+// CHECK-LABEL: define void @_Z1ev(
+// CHECK: call void @_ZN1AC1Ev(%struct.A* nonnull @_ZZ1evE1a)
+// CHECK: call {{.*}}@llvm.invariant.start.p0i8(i64 4, i8* {{.*}}bitcast ({{.*}} @_ZZ1evE1a to i8*))
+// CHECK-NOT: llvm.invariant.end
diff --git a/src/llvm-project/clang/test/CodeGenCXX/init-priority-attr.cpp b/src/llvm-project/clang/test/CodeGenCXX/init-priority-attr.cpp
new file mode 100644
index 0000000..ff155d0
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/init-priority-attr.cpp
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -O2 -emit-llvm -o - | FileCheck %s
+// PR11480
+
+void foo(int);
+
+class A {
+public:
+ A() { foo(1); }
+};
+
+class A1 {
+public:
+ A1() { foo(2); }
+};
+
+class B {
+public:
+ B() { foo(3); }
+};
+
+class C {
+public:
+ static A a;
+ C() { foo(4); }
+};
+
+
+A C::a = A();
+
+// CHECK: @llvm.global_ctors = appending global [3 x { i32, void ()*, i8* }]
+// CHECK: [{ i32, void ()*, i8* } { i32 200, void ()* @_GLOBAL__I_000200, i8* null },
+// CHECK: { i32, void ()*, i8* } { i32 300, void ()* @_GLOBAL__I_000300, i8* null },
+// CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_init_priority_attr.cpp, i8* null }]
+
+// CHECK: _GLOBAL__I_000200()
+// CHECK: _Z3fooi(i32 3)
+// CHECK-NEXT: ret void
+
+// CHECK: _GLOBAL__I_000300()
+// CHECK: _Z3fooi(i32 2)
+// CHECK-NEXT: _Z3fooi(i32 1)
+// CHECK-NEXT: ret void
+
+// CHECK: _GLOBAL__sub_I_init_priority_attr.cpp()
+// CHECK: _Z3fooi(i32 1)
+// CHECK-NEXT: _Z3fooi(i32 4)
+// CHECK-NEXT: ret void
+
+C c;
+A1 a1 __attribute__((init_priority (300)));
+A a __attribute__((init_priority (300)));
+B b __attribute__((init_priority (200)));
diff --git a/src/llvm-project/clang/test/CodeGenCXX/initializer-list-ctor-order.cpp b/src/llvm-project/clang/test/CodeGenCXX/initializer-list-ctor-order.cpp
new file mode 100644
index 0000000..6bb9c1b
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/initializer-list-ctor-order.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -std=c++11 %s -emit-llvm -o - -triple i686-linux-gnu | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ITANIUM
+// RUN: %clang_cc1 -std=c++11 %s -emit-llvm -o - -triple i686-windows | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-MS
+
+extern "C" {
+int f();
+int g();
+}
+
+struct A {
+ A(int, int);
+};
+
+
+void foo() {
+ A a{f(), g()};
+}
+// CHECK-ITANIUM-LABEL: define void @_Z3foov
+// CHECK-MS-LABEL: define dso_local void @"?foo@@YAXXZ"
+// CHECK: call i32 @f()
+// CHECK: call i32 @g()
+
+struct B : A {
+ B();
+};
+B::B() : A{f(), g()} {}
+// CHECK-ITANIUM-LABEL: define void @_ZN1BC2Ev
+// CHECK-MS-LABEL: define dso_local x86_thiscallcc %struct.B* @"??0B@@QAE@XZ"
+// CHECK: call i32 @f()
+// CHECK: call i32 @g()
diff --git a/src/llvm-project/clang/test/CodeGenCXX/inline-dllexport-member.cpp b/src/llvm-project/clang/test/CodeGenCXX/inline-dllexport-member.cpp
new file mode 100644
index 0000000..d6b004d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/inline-dllexport-member.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -triple i686-windows-win32 -fms-extensions -debug-info-kind=limited -emit-llvm %s -o - \
+// RUN: | FileCheck %s
+
+// CHECK: @"?ui@s@@2IB" = weak_odr dso_local dllexport constant i32 0, comdat, align 4, !dbg [[UI:![0-9]+]]
+
+struct __declspec(dllexport) s {
+ static const unsigned int ui = 0;
+};
+
+// CHECK: [[UI]] = !DIGlobalVariableExpression(var: [[UIV:.*]], expr: !DIExpression())
+// CHECK: [[UIV]] = distinct !DIGlobalVariable(name: "ui", linkageName: "?ui@s@@2IB", scope: ![[SCOPE:[0-9]+]],
+// CHECK: ![[SCOPE]] = distinct !DICompileUnit(
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/inline-functions.cpp b/src/llvm-project/clang/test/CodeGenCXX/inline-functions.cpp
new file mode 100644
index 0000000..95aec8b
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/inline-functions.cpp
@@ -0,0 +1,150 @@
+// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s --check-prefix=CHECK --check-prefix=NORMAL
+// RUN: %clang_cc1 %s -std=c++11 -fms-compatibility -triple=x86_64-pc-win32 -emit-llvm -o - | FileCheck %s --check-prefix=CHECK --check-prefix=MSVCCOMPAT
+// CHECK: ; ModuleID
+
+struct A {
+ inline void f();
+};
+
+// NORMAL-NOT: define void @_ZN1A1fEv
+// MSVCCOMPAT-NOT: define void @"?f@A@@QEAAXXZ"
+void A::f() { }
+
+template<typename> struct B { };
+
+template<> struct B<char> {
+ inline void f();
+};
+
+// NORMAL-NOT: _ZN1BIcE1fEv
+// MSVCCOMPAT-NOT: @"?f@?$B@D@@QEAAXXZ"
+void B<char>::f() { }
+
+// We need a final CHECK line here.
+
+// NORMAL-LABEL: define void @_Z1fv
+// MSVCCOMPAT-LABEL: define dso_local void @"?f@@YAXXZ"
+void f() { }
+
+// <rdar://problem/8740363>
+inline void f1(int);
+
+// NORMAL-LABEL: define linkonce_odr void @_Z2f1i
+// MSVCCOMPAT-LABEL: define linkonce_odr dso_local void @"?f1@@YAXH@Z"
+void f1(int) { }
+
+void test_f1() { f1(17); }
+
+// PR8789
+namespace test1 {
+ template <typename T> class ClassTemplate {
+ private:
+ friend void T::func();
+ void g() {}
+ };
+
+ // NORMAL-LABEL: define linkonce_odr void @_ZN5test11C4funcEv(
+ // MSVCCOMPAT-LABEL: define linkonce_odr dso_local void @"?func@C@test1@@QEAAXXZ"(
+
+ class C {
+ public:
+ void func() {
+ ClassTemplate<C> ct;
+ ct.g();
+ }
+ };
+
+ void f() {
+ C c;
+ c.func();
+ }
+}
+
+// PR13252
+namespace test2 {
+ struct A;
+ void f(const A& a);
+ struct A {
+ friend void f(const A& a) { }
+ };
+ void g() {
+ A a;
+ f(a);
+ }
+ // NORMAL-LABEL: define linkonce_odr void @_ZN5test21fERKNS_1AE
+ // MSVCCOMPAT-LABEL: define linkonce_odr dso_local void @"?f@test2@@YAXAEBUA@1@@Z"
+}
+
+// NORMAL-NOT: _Z17ExternAndInlineFnv
+// MSVCCOMPAT-LABEL: define weak_odr dso_local void @"?ExternAndInlineFn@@YAXXZ"
+extern inline void ExternAndInlineFn() {}
+
+// NORMAL-NOT: _Z18InlineThenExternFnv
+// MSVCCOMPAT-LABEL: define weak_odr dso_local void @"?InlineThenExternFn@@YAXXZ"
+inline void InlineThenExternFn() {}
+extern void InlineThenExternFn();
+
+// NORMAL-LABEL: define void @_Z18ExternThenInlineFnv
+// MSVCCOMPAT-LABEL: define dso_local void @"?ExternThenInlineFn@@YAXXZ"
+extern void ExternThenInlineFn() {}
+
+// NORMAL-NOT: _Z25ExternThenInlineThenDefFnv
+// MSVCCOMPAT-LABEL: define weak_odr dso_local void @"?ExternThenInlineThenDefFn@@YAXXZ"
+extern void ExternThenInlineThenDefFn();
+inline void ExternThenInlineThenDefFn();
+void ExternThenInlineThenDefFn() {}
+
+// NORMAL-NOT: _Z25InlineThenExternThenDefFnv
+// MSVCCOMPAT-LABEL: define weak_odr dso_local void @"?InlineThenExternThenDefFn@@YAXXZ"
+inline void InlineThenExternThenDefFn();
+extern void InlineThenExternThenDefFn();
+void InlineThenExternThenDefFn() {}
+
+// NORMAL-NOT: _Z17ExternAndConstexprFnv
+// MSVCCOMPAT-LABEL: define weak_odr dso_local i32 @"?ExternAndConstexprFn@@YAHXZ"
+extern constexpr int ExternAndConstexprFn() { return 0; }
+
+// NORMAL-NOT: _Z11ConstexprFnv
+// MSVCCOMPAT-NOT: @"?ConstexprFn@@YAHXZ"
+constexpr int ConstexprFn() { return 0; }
+
+template <typename T>
+extern inline void ExternInlineOnPrimaryTemplate(T);
+
+// NORMAL-LABEL: define void @_Z29ExternInlineOnPrimaryTemplateIiEvT_
+// MSVCCOMPAT-LABEL: define dso_local void @"??$ExternInlineOnPrimaryTemplate@H@@YAXH@Z"
+template <>
+void ExternInlineOnPrimaryTemplate(int) {}
+
+template <typename T>
+extern inline void ExternInlineOnPrimaryTemplateAndSpecialization(T);
+
+// NORMAL-NOT: _Z46ExternInlineOnPrimaryTemplateAndSpecializationIiEvT_
+// MSVCCOMPAT-LABEL: define weak_odr dso_local void @"??$ExternInlineOnPrimaryTemplateAndSpecialization@H@@YAXH@Z"
+template <>
+extern inline void ExternInlineOnPrimaryTemplateAndSpecialization(int) {}
+
+struct TypeWithInlineMethods {
+ // NORMAL-NOT: _ZN21TypeWithInlineMethods9StaticFunEv
+ // MSVCCOMPAT-NOT: @"?StaticFun@TypeWithInlineMethods@@SAXXZ"
+ static void StaticFun() {}
+ // NORMAL-NOT: _ZN21TypeWithInlineMethods12NonStaticFunEv
+ // MSVCCOMPAT-NOT: @"?NonStaticFun@TypeWithInlineMethods@@QEAAXXZ"
+ void NonStaticFun() { StaticFun(); }
+};
+
+namespace PR22959 {
+template <typename>
+struct S;
+
+S<int> Foo();
+
+template <typename>
+struct S {
+ friend S<int> Foo();
+};
+
+__attribute__((used)) inline S<int> Foo() { return S<int>(); }
+// NORMAL-LABEL: define linkonce_odr void @_ZN7PR229593FooEv(
+// MSVCCOMPAT-LABEL: define linkonce_odr dso_local i8 @"?Foo@PR22959@@YA?AU?$S@H@1@XZ"(
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/inline-hint.cpp b/src/llvm-project/clang/test/CodeGenCXX/inline-hint.cpp
new file mode 100644
index 0000000..e8c067d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/inline-hint.cpp
@@ -0,0 +1,96 @@
+// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-linux -O2 -finline-functions -emit-llvm -disable-llvm-passes -o - | FileCheck -allow-deprecated-dag-overlap %s --check-prefix=CHECK --check-prefix=SUITABLE
+// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-linux -O2 -finline-hint-functions -emit-llvm -disable-llvm-passes -o - | FileCheck -allow-deprecated-dag-overlap %s --check-prefix=CHECK --check-prefix=HINTED
+// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-linux -O2 -fno-inline -emit-llvm -disable-llvm-passes -o - | FileCheck -allow-deprecated-dag-overlap %s --check-prefix=CHECK --check-prefix=NOINLINE
+
+// Force non-trivial implicit constructors/destructors/operators for B by having explicit ones for A
+struct A {
+ A() {}
+ A(const A&) {}
+ A& operator=(const A&) { return *this; }
+ ~A() {}
+};
+
+struct B {
+ A member;
+ int implicitFunction(int a) { return a + a; }
+ inline int explicitFunction(int a);
+ int noHintFunction(int a);
+ __attribute__((optnone)) int optNoneFunction(int a) { return a + a; }
+ template<int N> int implicitTplFunction(int a) { return N + a; }
+ template<int N> inline int explicitTplFunction(int a) { return N + a; }
+ template<int N> int noHintTplFunction(int a);
+ template<int N> int explicitRedeclTplFunction(int a);
+};
+
+int B::explicitFunction(int a) { return a + a; }
+// CHECK: @_ZN1B14noHintFunctionEi({{.*}}) [[NOHINT_ATTR:#[0-9]+]]
+int B::noHintFunction(int a) { return a + a; }
+
+// CHECK: @_ZN1B19implicitTplFunctionILi0EEEii({{.*}}) [[NOHINT_ATTR]]
+template<> int B::implicitTplFunction<0>(int a) { return a + a; }
+// CHECK: @_ZN1B19explicitTplFunctionILi0EEEii({{.*}}) [[NOHINT_ATTR]]
+template<> int B::explicitTplFunction<0>(int a) { return a + a; }
+// CHECK: @_ZN1B17noHintTplFunctionILi0EEEii({{.*}}) [[NOHINT_ATTR]]
+template<> int B::noHintTplFunction<0>(int a) { return a + a; }
+template<> inline int B::implicitTplFunction<1>(int a) { return a; }
+template<> inline int B::explicitTplFunction<1>(int a) { return a; }
+template<> inline int B::noHintTplFunction<1>(int a) { return a; }
+template<int N> int B::noHintTplFunction(int a) { return N + a; }
+template<int N> inline int B::explicitRedeclTplFunction(int a) { return N + a; }
+
+constexpr int constexprFunction(int a) { return a + a; }
+
+void foo()
+{
+// CHECK: @_ZN1BC1Ev({{.*}}) unnamed_addr [[IMPLICIT_CONSTR_ATTR:#[0-9]+]]
+ B b1;
+// CHECK: @_ZN1BC1ERKS_({{.*}}) unnamed_addr [[IMPLICIT_CONSTR_ATTR]]
+ B b2(b1);
+// CHECK: @_ZN1BaSERKS_({{.*}}) [[IMPLICIT_CONSTR_ATTR]]
+ b2 = b1;
+// CHECK: @_ZN1B16implicitFunctionEi({{.*}}) [[IMPLICIT_ATTR:#[0-9]+]]
+ b1.implicitFunction(1);
+// CHECK: @_ZN1B16explicitFunctionEi({{.*}}) [[EXPLICIT_ATTR:#[0-9]+]]
+ b1.explicitFunction(2);
+ b1.noHintFunction(3);
+// CHECK: @_ZN1B15optNoneFunctionEi({{.*}}) [[OPTNONE_ATTR:#[0-9]+]]
+ b1.optNoneFunction(4);
+// CHECK: @_Z17constexprFunctioni({{.*}}) [[IMPLICIT_ATTR]]
+ constexprFunction(5);
+ b1.implicitTplFunction<0>(6);
+// CHECK: @_ZN1B19implicitTplFunctionILi1EEEii({{.*}}) [[EXPLICIT_ATTR]]
+ b1.implicitTplFunction<1>(7);
+// CHECK: @_ZN1B19implicitTplFunctionILi2EEEii({{.*}}) [[IMPLICIT_ATTR]]
+ b1.implicitTplFunction<2>(8);
+ b1.explicitTplFunction<0>(9);
+// CHECK: @_ZN1B19explicitTplFunctionILi1EEEii({{.*}}) [[EXPLICIT_ATTR]]
+ b1.explicitTplFunction<1>(10);
+// CHECK: @_ZN1B19explicitTplFunctionILi2EEEii({{.*}}) [[EXPLICIT_ATTR]]
+ b1.explicitTplFunction<2>(11);
+ b1.noHintTplFunction<0>(12);
+// CHECK: @_ZN1B17noHintTplFunctionILi1EEEii({{.*}}) [[EXPLICIT_ATTR]]
+ b1.noHintTplFunction<1>(13);
+// CHECK: @_ZN1B17noHintTplFunctionILi2EEEii({{.*}}) [[NOHINT_ATTR]]
+ b1.noHintTplFunction<2>(14);
+// CHECK: @_ZN1B25explicitRedeclTplFunctionILi2EEEii({{.*}}) [[EXPLICIT_ATTR]]
+ b1.explicitRedeclTplFunction<2>(15);
+// CHECK: @_ZN1BD2Ev({{.*}}) unnamed_addr [[IMPLICIT_CONSTR_ATTR]]
+}
+
+// SUITABLE-NOT: attributes [[NOHINT_ATTR]] = { {{.*}}noinline{{.*}} }
+// HINTED-DAG: attributes [[NOHINT_ATTR]] = { noinline{{.*}} }
+// NOINLINE-DAG: attributes [[NOHINT_ATTR]] = { noinline{{.*}} }
+
+// SUITABLE-NOT: attributes [[IMPLICIT_ATTR]] = { {{.*}}noinline{{.*}} }
+// HINTED-NOT: attributes [[IMPLICIT_ATTR]] = { {{.*}}noinline{{.*}} }
+// NOINLINE-DAG: attributes [[IMPLICIT_ATTR]] = { noinline{{.*}} }
+
+// SUITABLE-NOT: attributes [[IMPLICIT_CONSTR_ATTR]] = { {{.*}}noinline{{.*}} }
+// HINTED-NOT: attributes [[IMPLICIT_ATTR]] = { {{.*}}noinline{{.*}} }
+// NOINLINE-DAG: attributes [[IMPLICIT_CONSTR_ATTR]] = { noinline{{.*}} }
+
+// SUITABLE-NOT: attributes [[EXPLICIT_ATTR]] = { {{.*}}noinline{{.*}} }
+// HINTED-NOT: attributes [[IMPLICIT_ATTR]] = { {{.*}}noinline{{.*}} }
+// NOINLINE-DAG: attributes [[EXPLICIT_ATTR]] = { noinline{{.*}} }
+
+// CHECK-DAG: attributes [[OPTNONE_ATTR]] = { noinline{{.*}} }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/inline-template-hint.cpp b/src/llvm-project/clang/test/CodeGenCXX/inline-template-hint.cpp
new file mode 100644
index 0000000..3e64b1f
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/inline-template-hint.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-linux -O2 \
+// RUN: -finline-functions -emit-llvm -disable-llvm-passes -o - \
+// RUN: | FileCheck -allow-deprecated-dag-overlap %s \
+// RUN: --check-prefix=CHECK --check-prefix=SUITABLE
+// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-linux -O2 \
+// RUN: -finline-hint-functions -emit-llvm -disable-llvm-passes -o - \
+// RUN: | FileCheck -allow-deprecated-dag-overlap %s \
+// RUN: --check-prefix=CHECK --check-prefix=HINTED
+// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-linux -O2 \
+// RUN: -fno-inline -emit-llvm -disable-llvm-passes -o - \
+// RUN: | FileCheck -allow-deprecated-dag-overlap %s \
+// RUN: --check-prefix=CHECK --check-prefix=NOINLINE
+
+struct A {
+ inline void int_run(int);
+
+ template <class T>
+ inline void template_run(T);
+};
+
+// CHECK: @_ZN1A7int_runEi({{.*}}) [[ATTR:#[0-9]+]]
+void A::int_run(int) {}
+// CHECK: @_ZN1A12template_runIiEEvT_({{.*}}) [[ATTR]]
+template <typename T>
+void A::template_run(T) {}
+
+void bar() {
+ A().int_run(1);
+ A().template_run(1);
+}
+
+// SUITABLE: attributes [[ATTR]] = { {{.*}}inlinehint{{.*}} }
+// HINTED: attributes [[ATTR]] = { {{.*}}inlinehint{{.*}} }
+// NOINLINE: attributes [[ATTR]] = { {{.*}}noinline{{.*}} }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/instantiate-blocks.cpp b/src/llvm-project/clang/test/CodeGenCXX/instantiate-blocks.cpp
new file mode 100644
index 0000000..e206582
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/instantiate-blocks.cpp
@@ -0,0 +1,59 @@
+// RUN: %clang_cc1 -fblocks -emit-llvm -o - %s
+// rdar : // 6182276
+
+template <typename T> T foo(T t)
+{
+ void (^block)(int);
+ return 1;
+}
+
+int test1(void)
+{
+ int i = 1;
+ int b = 2;
+ i = foo(b);
+ return 0;
+}
+
+template <typename T, typename T1> void foo(T t, T1 r)
+{
+ T block_arg;
+ __block T1 byref_block_arg;
+
+ T1 (^block)(char, T, T1, double) =
+ ^ T1 (char ch, T arg, T1 arg2, double d1) { byref_block_arg = arg2;
+ return byref_block_arg + block_arg + arg; };
+
+ void (^block2)() = ^{};
+}
+
+void test2(void)
+{
+ foo(100, 'a');
+}
+
+namespace rdar6182276 {
+extern "C" {
+int printf(const char *, ...);
+}
+
+template <typename T> T foo(T t)
+{
+ void (^testing)(int) = ^(int bar) { printf("bar is %d\n", bar); };
+ printf("bar is\n");
+ return 1;
+}
+
+template <typename T> void gorf(T t)
+{
+ foo(t);
+}
+
+
+void test(void)
+{
+ gorf(2);
+}
+}
+
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/instantiate-init-list.cpp b/src/llvm-project/clang/test/CodeGenCXX/instantiate-init-list.cpp
new file mode 100644
index 0000000..e498d24
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/instantiate-init-list.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 %s -emit-llvm-only -verify
+// expected-no-diagnostics
+
+struct F {
+ void (*x)();
+};
+void G();
+template<class T> class A {
+public: A();
+};
+template<class T> A<T>::A() {
+ static F f = { G };
+}
+A<int> a;
diff --git a/src/llvm-project/clang/test/CodeGenCXX/instantiate-temporaries.cpp b/src/llvm-project/clang/test/CodeGenCXX/instantiate-temporaries.cpp
new file mode 100644
index 0000000..c08ea78
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/instantiate-temporaries.cpp
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.7.0 -emit-llvm -o - %s | FileCheck %s
+
+struct X {
+ X();
+ ~X();
+};
+
+struct Y {
+ X get();
+};
+
+struct X2 {
+ X x;
+};
+
+template<typename T>
+void call() {
+ Y().get();
+}
+
+// CHECK-LABEL: define weak_odr void @_Z4callIiEvv
+// CHECK: call void @_ZN1Y3getEv
+// CHECK-NEXT: call void @_ZN1XD1Ev
+// CHECK-NEXT: ret void
+template void call<int>();
+
+template<typename T>
+void compound_literal() {
+ (X2){};
+}
+
+// CHECK-LABEL: define weak_odr void @_Z16compound_literalIiEvv
+// CHECK: call void @_ZN1XC1Ev
+// CHECK-NEXT: call void @_ZN2X2D1Ev
+// CHECK-NEXT: ret void
+template void compound_literal<int>();
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/instrument-functions.cpp b/src/llvm-project/clang/test/CodeGenCXX/instrument-functions.cpp
new file mode 100644
index 0000000..45ae482
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/instrument-functions.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -S -emit-llvm -triple %itanium_abi_triple -o - %s -finstrument-functions -disable-llvm-passes | FileCheck %s
+
+int test1(int x) {
+// CHECK: @_Z5test1i(i32 {{.*}}%x) #[[ATTR1:[0-9]+]]
+// CHECK: ret
+ return x;
+}
+
+int test2(int) __attribute__((no_instrument_function));
+int test2(int x) {
+// CHECK: @_Z5test2i(i32 {{.*}}%x) #[[ATTR2:[0-9]+]]
+// CHECK: ret
+ return x;
+}
+
+// CHECK: attributes #[[ATTR1]] =
+// CHECK-SAME: "instrument-function-entry"="__cyg_profile_func_enter"
+// CHECK-SAME: "instrument-function-exit"="__cyg_profile_func_exit"
+
+// CHECK: attributes #[[ATTR2]] =
+// CHECK-NOT: "instrument-function-entry"
+
+
+// This test case previously crashed code generation. It exists solely
+// to test -finstrument-function does not crash codegen for this trivial
+// case.
+namespace rdar9445102 {
+ class Rdar9445102 {
+ public:
+ Rdar9445102();
+ };
+}
+static rdar9445102::Rdar9445102 s_rdar9445102Initializer;
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/int64_uint64.cpp b/src/llvm-project/clang/test/CodeGenCXX/int64_uint64.cpp
new file mode 100644
index 0000000..aad6ea0
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/int64_uint64.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple arm-linux-guneabi \
+// RUN: -target-cpu cortex-a8 \
+// RUN: -emit-llvm -w -O1 -o - %s | FileCheck --check-prefix=CHECK-ARM %s
+
+// RUN: %clang_cc1 -triple arm64-linux-gnueabi \
+// RUN: -target-feature +neon \
+// RUN: -emit-llvm -w -O1 -o - %s | FileCheck --check-prefix=CHECK-AARCH64 %s
+
+// Test if int64_t and uint64_t can be correctly mangled.
+
+#include "arm_neon.h"
+// CHECK-ARM: f1x(
+// CHECK-AARCH64: f1l(
+void f1(int64_t a) {}
+// CHECK-ARM: f2y(
+// CHECK-AARCH64: f2m(
+void f2(uint64_t a) {}
+// CHECK-ARM: f3Px(
+// CHECK-AARCH64: f3Pl(
+void f3(int64_t *ptr) {}
+// CHECK-ARM: f4Py(
+// CHECK-AARCH64: f4Pm(
+void f4(uint64_t *ptr) {}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/internal-linkage.cpp b/src/llvm-project/clang/test/CodeGenCXX/internal-linkage.cpp
new file mode 100644
index 0000000..f3c0ad1
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/internal-linkage.cpp
@@ -0,0 +1,64 @@
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -o - %s | FileCheck %s
+
+struct Global { Global(); };
+template<typename T> struct X { X() {} };
+
+
+namespace {
+ struct Anon { Anon() {} };
+
+ // CHECK: @_ZN12_GLOBAL__N_15anon0E = internal global
+ Global anon0;
+}
+
+// CHECK: @anon1 = internal global
+Anon anon1;
+
+// CHECK: @anon2 = internal global
+X<Anon> anon2;
+
+// rdar: // 8071804
+char const * const xyzzy = "Hello, world!";
+extern char const * const xyzzy;
+
+char const * const *test1()
+{
+ // CHECK: @_ZL5xyzzy = internal constant
+ return &xyzzy;
+}
+
+static char const * const static_xyzzy = "Hello, world!";
+extern char const * const static_xyzzy;
+
+char const * const *test2()
+{
+ // CHECK: @_ZL12static_xyzzy = internal constant
+ return &static_xyzzy;
+}
+
+static char const * static_nonconst_xyzzy = "Hello, world!";
+extern char const * static_nonconst_xyzzy;
+
+char const * *test3()
+{
+ // CHECK: @_ZL21static_nonconst_xyzzy = internal global
+ return &static_nonconst_xyzzy;
+}
+
+
+char const * extern_nonconst_xyzzy = "Hello, world!";
+extern char const * extern_nonconst_xyzzy;
+
+char const * *test4()
+{
+ // CHECK: @extern_nonconst_xyzzy = {{(dso_local )?}}global
+ return &extern_nonconst_xyzzy;
+}
+
+// PR10120
+template <typename T> class klass {
+ virtual void f();
+};
+namespace { struct S; }
+void foo () { klass<S> x; }
+// CHECK: @_ZTV5klassIN12_GLOBAL__N_11SEE = internal unnamed_addr constant
diff --git a/src/llvm-project/clang/test/CodeGenCXX/invalid.cpp b/src/llvm-project/clang/test/CodeGenCXX/invalid.cpp
new file mode 100644
index 0000000..d346246
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/invalid.cpp
@@ -0,0 +1,11 @@
+// RUN: not %clang_cc1 -g -emit-llvm %s
+
+// Don't attempt to codegen invalid code that would lead to a crash
+
+// PR16933
+struct A;
+A *x;
+struct A {
+ B y;
+};
+A y;
diff --git a/src/llvm-project/clang/test/CodeGenCXX/invariant.group-for-vptrs.cpp b/src/llvm-project/clang/test/CodeGenCXX/invariant.group-for-vptrs.cpp
new file mode 100644
index 0000000..d4f80dd
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/invariant.group-for-vptrs.cpp
@@ -0,0 +1,71 @@
+// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -emit-llvm %s -fstrict-vtable-pointers -O1 -o - -disable-llvm-passes | FileCheck %s
+
+struct A {
+ virtual void foo();
+};
+
+struct D : A {
+ void foo();
+};
+
+// CHECK-LABEL: define void @_Z21testExternallyVisiblev()
+void testExternallyVisible() {
+ A *a = new A;
+
+ // CHECK: load {{.*}} !invariant.group ![[MD:[0-9]+]]
+ a->foo();
+
+ D *d = new D;
+ // CHECK: call void @_ZN1DC1Ev(
+ // CHECK: load {{.*}} !invariant.group ![[MD]]
+ d->foo();
+ A *a2 = d;
+ // CHECK: load {{.*}} !invariant.group ![[MD]]
+ a2->foo();
+}
+// CHECK-LABEL: {{^}}}
+
+namespace {
+
+struct B {
+ virtual void bar();
+};
+
+struct C : B {
+ void bar();
+};
+
+}
+
+// CHECK-LABEL: define void @_Z21testInternallyVisibleb(
+void testInternallyVisible(bool p) {
+ B *b = new B;
+ // CHECK: = load {{.*}}, !invariant.group ![[MD]]
+ b->bar();
+
+ // CHECK: call void @_ZN12_GLOBAL__N_11CC1Ev(
+ C *c = new C;
+ // CHECK: = load {{.*}}, !invariant.group ![[MD]]
+ c->bar();
+}
+
+// Checking A::A()
+// CHECK-LABEL: define linkonce_odr void @_ZN1AC2Ev(
+// CHECK: store {{.*}}, !invariant.group ![[MD]]
+// CHECK-LABEL: {{^}}}
+
+// Checking D::D()
+// CHECK-LABEL: define linkonce_odr void @_ZN1DC2Ev(
+// CHECK: = call i8* @llvm.launder.invariant.group.p0i8(i8*
+// CHECK: call void @_ZN1AC2Ev(%struct.A*
+// CHECK: store {{.*}} !invariant.group ![[MD]]
+
+// Checking B::B()
+// CHECK-LABEL: define internal void @_ZN12_GLOBAL__N_11BC2Ev(
+// CHECK: store {{.*}}, !invariant.group ![[MD]]
+
+// Checking C::C()
+// CHECK-LABEL: define internal void @_ZN12_GLOBAL__N_11CC2Ev(
+// CHECK: store {{.*}}, !invariant.group ![[MD]]
+
+// CHECK: ![[MD]] = !{}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/key-function-vtable.cpp b/src/llvm-project/clang/test/CodeGenCXX/key-function-vtable.cpp
new file mode 100644
index 0000000..028017c
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/key-function-vtable.cpp
@@ -0,0 +1,51 @@
+// RUN: %clang_cc1 -triple x86_64-none-linux-gnu %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple arm-apple-darwin %s -emit-llvm -o - | FileCheck %s
+
+// Simple key function test
+struct testa { virtual void a(); };
+void testa::a() {}
+
+// Simple key function test
+struct testb { virtual void a() {} };
+testb *testbvar = new testb;
+
+// Key function with out-of-line inline definition
+struct testc { virtual void a(); };
+inline void testc::a() {}
+
+// Functions with inline specifier are not key functions (PR5705)
+struct testd { inline virtual void a(); };
+void testd::a() {}
+
+// Functions with inline specifier are not key functions (PR5705)
+struct teste { inline virtual void a(); };
+teste *testevar = new teste;
+
+// Key functions with namespace (PR5711)
+namespace {
+ struct testf { virtual void a(); };
+}
+void testf::a() {}
+
+// Key functions with namespace (PR5711)
+namespace {
+ struct testg { virtual void a(); };
+}
+void testg::a() {}
+testg *testgvar = new testg;
+
+struct X0 { virtual ~X0(); };
+struct X1 : X0 {
+ virtual void f();
+};
+
+inline void X1::f() { }
+
+void use_X1() { X1 x1; }
+
+// CHECK-DAG: @_ZTV2X1 = linkonce_odr unnamed_addr constant
+// CHECK-DAG: @_ZTV5testa = unnamed_addr constant { [3 x i8*] } { [3 x i8*] [i8* null
+// CHECK-DAG: @_ZTV5testc = linkonce_odr unnamed_addr constant { [3 x i8*] } { [3 x i8*] [i8* null
+// CHECK-DAG: @_ZTV5testb = linkonce_odr unnamed_addr constant { [3 x i8*] } { [3 x i8*] [i8* null
+// CHECK-DAG: @_ZTV5teste = linkonce_odr unnamed_addr constant { [3 x i8*] } { [3 x i8*] [i8* null
+// CHECK-DAG: @_ZTVN12_GLOBAL__N_15testgE = internal unnamed_addr constant { [3 x i8*] } { [3 x i8*] [i8* null
diff --git a/src/llvm-project/clang/test/CodeGenCXX/lambda-expressions-inside-auto-functions.cpp b/src/llvm-project/clang/test/CodeGenCXX/lambda-expressions-inside-auto-functions.cpp
new file mode 100644
index 0000000..59acba7
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/lambda-expressions-inside-auto-functions.cpp
@@ -0,0 +1,80 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -fblocks -emit-llvm -o - %s -fexceptions -std=c++1y | FileCheck --check-prefix CHECK_ABI_LATEST %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -fblocks -emit-llvm -o - %s -fexceptions -std=c++1y -fclang-abi-compat=6.0 | FileCheck --check-prefix CHECK_ABIV6 %s
+
+// CHECK-LABEL: define void @_ZN19non_inline_function3fooEv
+// CHECK-LABEL: define internal void @"_ZZN19non_inline_function3fooEvENK3$_0clEi"(%class.anon
+// CHECK-LABEL: define internal signext i8 @"_ZZZN19non_inline_function3fooEvENK3$_0clEiENKUlcE_clEc"(%class.anon
+// CHECK-LABEL: define linkonce_odr void @_ZN19non_inline_function4foo2IiEEDav()
+namespace non_inline_function {
+auto foo() {
+ auto L = [](int a) {
+ return [](char b) {
+ return b;
+ };
+ };
+ L(3)('a');
+ return L;
+}
+
+template<typename T>
+auto foo2() {
+ return [](const T&) { return 42; };
+}
+
+auto use = foo2<int>();
+
+}
+//CHECK-LABEL: define linkonce_odr void @_ZN22inline_member_function1X3fooEv(%"struct.inline_member_function::X"* %this)
+//CHECK-LABEL: define linkonce_odr void @_ZZN22inline_member_function1X3fooEvENKUliE_clEi(%class.anon
+//CHECK-LABEL: define linkonce_odr signext i8 @_ZZZN22inline_member_function1X3fooEvENKUliE_clEiENKUlcE_clEc(%class.anon
+
+namespace inline_member_function {
+struct X {
+auto foo() {
+ auto L = [](int a) {
+ return [](char b) {
+ return b;
+ };
+ };
+ return L;
+}
+};
+
+auto run1 = X{}.foo()(3)('a');
+
+template<typename S>
+struct A {
+ template<typename T> static auto default_lambda() {
+ return [](const T&) { return 42; };
+ }
+
+ template<class U = decltype(default_lambda<S>())>
+ U func(U u = default_lambda<S>()) { return u; }
+
+ template<class T> auto foo() { return [](const T&) { return 42; }; }
+};
+//CHECK_ABIV6: define linkonce_odr i32 @_ZZN22inline_member_function1AIdE14default_lambdaIdEEDavENKUlRKdE_clES5_(%class.anon
+//CHECK_ABI_LATEST: define linkonce_odr i32 @_ZZN22inline_member_function1AIdE14default_lambdaIdEEDavENKUlRKdE_clES4_(%class.anon
+int run2 = A<double>{}.func()(3.14);
+
+//CHECK_ABIV6: define linkonce_odr i32 @_ZZN22inline_member_function1AIcE14default_lambdaIcEEDavENKUlRKcE_clES5_(%class.anon
+//CHECK_ABI_LATEST: define linkonce_odr i32 @_ZZN22inline_member_function1AIcE14default_lambdaIcEEDavENKUlRKcE_clES4_(%class.anon
+int run3 = A<char>{}.func()('a');
+} // end inline_member_function
+
+
+// CHECK-LABEL: define linkonce_odr void @_ZN15inline_function3fooEv()
+// CHECK: define linkonce_odr void @_ZZN15inline_function3fooEvENKUliE_clEi(%class.anon
+// CHECK: define linkonce_odr signext i8 @_ZZZN15inline_function3fooEvENKUliE_clEiENKUlcE_clEc(%class.anon
+namespace inline_function {
+inline auto foo() {
+ auto L = [](int a) {
+ return [](char b) {
+ return b;
+ };
+ };
+ return L;
+}
+auto use = foo()(3)('a');
+}
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/lambda-expressions-nested-linkage.cpp b/src/llvm-project/clang/test/CodeGenCXX/lambda-expressions-nested-linkage.cpp
new file mode 100644
index 0000000..9a44987
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/lambda-expressions-nested-linkage.cpp
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -fblocks -emit-llvm -o - %s -fexceptions -std=c++11 | FileCheck %s
+
+// CHECK-LABEL: define void @_ZN19non_inline_function3fooEv()
+// CHECK-LABEL: define internal void @"_ZZN19non_inline_function3fooEvENK3$_0clEi"(%class.anon
+// CHECK-LABEL: define internal signext i8 @"_ZZZN19non_inline_function3fooEvENK3$_0clEiENKUlcE_clEc"(%class.anon
+namespace non_inline_function {
+void foo() {
+ auto L = [](int a) {
+ return [](char b) {
+ return b;
+ };
+ };
+ L(3)('a');
+}
+}
+
+namespace non_template {
+ struct L {
+ int t = ([](int a) { return [](int b) { return b; };})(2)(3);
+ };
+ L l;
+}
+
+namespace lambdas_in_NSDMIs_template_class {
+template<class T>
+struct L {
+ T t2 = ([](int a) { return [](int b) { return b; };})(T{})(T{});
+};
+L<int> l;
+}
+
+// CHECK-LABEL: define linkonce_odr i32 @_ZN15inline_function3fooEv
+
+// CHECK-LABEL: define linkonce_odr void @_ZNK12non_template1L1tMUliE_clEi(%class.anon
+// CHECK-LABEL: define linkonce_odr i32 @_ZZNK12non_template1L1tMUliE_clEiENKUliE_clEi(%class.anon
+
+
+// CHECK-LABEL: define linkonce_odr void @_ZNK32lambdas_in_NSDMIs_template_class1LIiEUliE_clEi(%class.anon
+// CHECK-LABEL: define linkonce_odr i32 @_ZZNK32lambdas_in_NSDMIs_template_class1LIiEUliE_clEiENKUliE_clEi(%class.anon
+
+// CHECK-LABEL: define linkonce_odr void @_ZZN15inline_function3fooEvENKUliE_clEi
+// CHECK-LABEL: define linkonce_odr signext i8 @_ZZZN15inline_function3fooEvENKUliE_clEiENKUlcE_clEc
+namespace inline_function {
+inline int foo() {
+ auto L = [](int a) {
+ return [](char b) {
+ return b;
+ };
+ };
+ L(3)('a');
+}
+int use = foo();
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/lambda-expressions.cpp b/src/llvm-project/clang/test/CodeGenCXX/lambda-expressions.cpp
new file mode 100644
index 0000000..2c625da
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/lambda-expressions.cpp
@@ -0,0 +1,224 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -fblocks -emit-llvm -o - %s -fexceptions -std=c++11 | FileCheck %s
+
+// CHECK-NOT: @unused
+auto unused = [](int i) { return i+1; };
+
+// CHECK: @used = internal global
+auto used = [](int i) { return i+1; };
+void *use = &used;
+
+// CHECK: @cvar = global
+extern "C" auto cvar = []{};
+
+// CHECK-LABEL: define i32 @_Z9ARBSizeOfi(i32
+int ARBSizeOf(int n) {
+ typedef double(T)[8][n];
+ using TT = double[8][n];
+ return [&]() -> int {
+ typedef double(T1)[8][n];
+ using TT1 = double[8][n];
+ return [&n]() -> int {
+ typedef double(T2)[8][n];
+ using TT2 = double[8][n];
+ return sizeof(T) + sizeof(T1) + sizeof(T2) + sizeof(TT) + sizeof(TT1) + sizeof(TT2);
+ }();
+ }();
+}
+
+// CHECK-LABEL: define internal i32 @"_ZZ9ARBSizeOfiENK3$_0clEv"
+
+int a() { return []{ return 1; }(); }
+// CHECK-LABEL: define i32 @_Z1av
+// CHECK: call i32 @"_ZZ1avENK3$_1clEv"
+// CHECK-LABEL: define internal i32 @"_ZZ1avENK3$_1clEv"
+// CHECK: ret i32 1
+
+int b(int x) { return [x]{return x;}(); }
+// CHECK-LABEL: define i32 @_Z1bi
+// CHECK: store i32
+// CHECK: load i32, i32*
+// CHECK: store i32
+// CHECK: call i32 @"_ZZ1biENK3$_2clEv"
+// CHECK-LABEL: define internal i32 @"_ZZ1biENK3$_2clEv"
+// CHECK: load i32, i32*
+// CHECK: ret i32
+
+int c(int x) { return [&x]{return x;}(); }
+// CHECK-LABEL: define i32 @_Z1ci
+// CHECK: store i32
+// CHECK: store i32*
+// CHECK: call i32 @"_ZZ1ciENK3$_3clEv"
+// CHECK-LABEL: define internal i32 @"_ZZ1ciENK3$_3clEv"
+// CHECK: load i32*, i32**
+// CHECK: load i32, i32*
+// CHECK: ret i32
+
+struct D { D(); D(const D&); int x; };
+int d(int x) { D y[10]; return [x,y] { return y[x].x; }(); }
+
+// CHECK-LABEL: define i32 @_Z1di
+// CHECK: call void @_ZN1DC1Ev
+// CHECK: br label
+// CHECK: call void @_ZN1DC1ERKS_
+// CHECK: icmp eq i64 %{{.*}}, 10
+// CHECK: br i1
+// CHECK: call i32 @"_ZZ1diENK3$_4clEv"
+// CHECK-LABEL: define internal i32 @"_ZZ1diENK3$_4clEv"
+// CHECK: load i32, i32*
+// CHECK: load i32, i32*
+// CHECK: ret i32
+
+struct E { E(); E(const E&); ~E(); int x; };
+int e(E a, E b, bool cond) { return [a,b,cond](){ return (cond ? a : b).x; }(); }
+// CHECK-LABEL: define i32 @_Z1e1ES_b
+// CHECK: call void @_ZN1EC1ERKS_
+// CHECK: invoke void @_ZN1EC1ERKS_
+// CHECK: invoke i32 @"_ZZ1e1ES_bENK3$_5clEv"
+// CHECK: call void @"_ZZ1e1ES_bEN3$_5D1Ev"
+// CHECK: call void @"_ZZ1e1ES_bEN3$_5D1Ev"
+
+// CHECK-LABEL: define internal i32 @"_ZZ1e1ES_bENK3$_5clEv"
+// CHECK: trunc i8
+// CHECK: load i32, i32*
+// CHECK: ret i32
+
+void f() {
+ // CHECK-LABEL: define void @_Z1fv()
+ // CHECK: @"_ZZ1fvENK3$_6cvPFiiiEEv"
+ // CHECK-NEXT: store i32 (i32, i32)*
+ // CHECK-NEXT: ret void
+ int (*fp)(int, int) = [](int x, int y){ return x + y; };
+}
+
+static int k;
+int g() {
+ int &r = k;
+ // CHECK-LABEL: define internal i32 @"_ZZ1gvENK3$_7clEv"(
+ // CHECK-NOT: }
+ // CHECK: load i32, i32* @_ZL1k,
+ return [] { return r; } ();
+};
+
+// PR14773
+// CHECK: [[ARRVAL:%[0-9a-zA-Z]*]] = load i32, i32* getelementptr inbounds ([0 x i32], [0 x i32]* @_ZZ14staticarrayrefvE5array, i64 0, i64 0), align 4
+// CHECK-NEXT: store i32 [[ARRVAL]]
+void staticarrayref(){
+ static int array[] = {};
+ (void)[](){
+ int (&xxx)[0] = array;
+ int y = xxx[0];
+ }();
+}
+
+// CHECK-LABEL: define internal i32* @"_ZZ11PR22071_funvENK3$_9clEv"
+// CHECK: ret i32* @PR22071_var
+int PR22071_var;
+int *PR22071_fun() {
+ constexpr int &y = PR22071_var;
+ return [&] { return &y; }();
+}
+
+namespace pr28595 {
+ struct Temp {
+ Temp();
+ ~Temp() noexcept(false);
+ };
+ struct A {
+ A();
+ A(const A &a, const Temp &temp = Temp());
+ ~A();
+ };
+
+ void after_init() noexcept;
+
+ // CHECK-LABEL: define void @_ZN7pr285954testEv()
+ void test() {
+ // CHECK: %[[SRC:.*]] = alloca [3 x [5 x %[[A:.*]]]], align 1
+ A array[3][5];
+
+ // Skip over the initialization loop.
+ // CHECK: call {{.*}}after_init
+ after_init();
+
+ // CHECK: %[[DST_0:.*]] = getelementptr {{.*}} [3 x [5 x %[[A]]]]* %[[DST:.*]], i64 0, i64 0
+ // CHECK: br label
+ // CHECK: %[[I:.*]] = phi i64 [ 0, %{{.*}} ], [ %[[I_NEXT:.*]], {{.*}} ]
+ // CHECK: %[[DST_I:.*]] = getelementptr {{.*}} [5 x %[[A]]]* %[[DST_0]], i64 %[[I]]
+ // CHECK: %[[SRC_I:.*]] = getelementptr {{.*}} [3 x [5 x %[[A]]]]* %[[SRC]], i64 0, i64 %[[I]]
+ //
+ // CHECK: %[[DST_I_0:.*]] = getelementptr {{.*}} [5 x %[[A]]]* %[[DST_I]], i64 0, i64 0
+ // CHECK: br label
+ // CHECK: %[[J:.*]] = phi i64 [ 0, %{{.*}} ], [ %[[J_NEXT:.*]], {{.*}} ]
+ // CHECK: %[[DST_I_J:.*]] = getelementptr {{.*}} %[[A]]* %[[DST_I_0]], i64 %[[J]]
+ // CHECK: %[[DST_0_0:.*]] = bitcast [5 x %[[A]]]* %[[DST_0]] to %[[A]]*
+ // CHECK: %[[SRC_I_J:.*]] = getelementptr {{.*}} [5 x %[[A]]]* %[[SRC_I]], i64 0, i64 %[[J]]
+ //
+ // CHECK: invoke void @_ZN7pr285954TempC1Ev
+ // CHECK: invoke void @_ZN7pr285951AC1ERKS0_RKNS_4TempE
+ // CHECK: invoke void @_ZN7pr285954TempD1Ev
+ //
+ // CHECK: add nuw i64 %[[J]], 1
+ // CHECK: icmp eq
+ // CHECK: br i1
+ //
+ // CHECK: add nuw i64 %[[I]], 1
+ // CHECK: icmp eq
+ // CHECK: br i1
+ //
+ // CHECK: ret void
+ //
+ // CHECK: landingpad
+ // CHECK: landingpad
+ // CHECK: br label %[[CLEANUP:.*]]{{$}}
+ // CHECK: landingpad
+ // CHECK: invoke void @_ZN7pr285954TempD1Ev
+ // CHECK: br label %[[CLEANUP]]
+ //
+ // CHECK: [[CLEANUP]]:
+ // CHECK: icmp eq %[[A]]* %[[DST_0_0]], %[[DST_I_J]]
+ // CHECK: %[[T0:.*]] = phi %[[A]]*
+ // CHECK: %[[T1:.*]] = getelementptr inbounds %[[A]], %[[A]]* %[[T0]], i64 -1
+ // CHECK: call void @_ZN7pr285951AD1Ev(%[[A]]* %[[T1]])
+ // CHECK: icmp eq %[[A]]* %[[T1]], %[[DST_0_0]]
+ (void) [array]{};
+ }
+}
+
+// CHECK-LABEL: define internal void @"_ZZ1e1ES_bEN3$_5D2Ev"
+
+// CHECK-LABEL: define internal i32 @"_ZZ1fvEN3$_68__invokeEii"
+// CHECK: store i32
+// CHECK-NEXT: store i32
+// CHECK-NEXT: load i32, i32*
+// CHECK-NEXT: load i32, i32*
+// CHECK-NEXT: call i32 @"_ZZ1fvENK3$_6clEii"
+// CHECK-NEXT: ret i32
+
+// CHECK-LABEL: define internal void @"_ZZ1hvEN4$_118__invokeEv"(%struct.A* noalias sret %agg.result) {{.*}} {
+// CHECK-NOT: =
+// CHECK: call void @"_ZZ1hvENK4$_11clEv"(%struct.A* sret %agg.result,
+// CHECK-NEXT: ret void
+struct A { ~A(); };
+void h() {
+ A (*h)() = [] { return A(); };
+}
+
+// <rdar://problem/12778708>
+struct XXX {};
+void nestedCapture () {
+ XXX localKey;
+ ^() {
+ [&]() {
+ ^{ XXX k = localKey; };
+ };
+ };
+}
+
+// Ensure we don't assert here.
+struct CaptureArrayAndThis {
+ CaptureArrayAndThis() {
+ char array[] = "floop";
+ [array, this] {};
+ }
+} capture_array_and_this;
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/lambda-to-function-pointer-conversion.cpp b/src/llvm-project/clang/test/CodeGenCXX/lambda-to-function-pointer-conversion.cpp
new file mode 100644
index 0000000..87d21a3
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/lambda-to-function-pointer-conversion.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc19.0.0 -std=c++11 -emit-llvm -o - %s | FileCheck %s
+
+// This code used to cause an assertion failure in EmitDelegateCallArg.
+
+// CHECK: define internal void @"?__invoke@<lambda_0>@?0??test@@YAXXZ@CA@UTrivial@@@Z"(
+// CHECK: call void @"??R<lambda_0>@?0??test@@YAXXZ@QEBA@UTrivial@@@Z"(
+
+// CHECK: define internal void @"??R<lambda_0>@?0??test@@YAXXZ@QEBA@UTrivial@@@Z"(
+
+struct Trivial {
+ int x;
+};
+
+void (*fnptr)(Trivial);
+
+void test() {
+ fnptr = [](Trivial a){ (void)a; };
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/lifetime-asan.cpp b/src/llvm-project/clang/test/CodeGenCXX/lifetime-asan.cpp
new file mode 100644
index 0000000..9ccb28c
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/lifetime-asan.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang -target x86_64-linux-gnu -S -emit-llvm -o - -fno-exceptions -O0 %s | FileCheck %s -check-prefixes=CHECK,CHECK-O0 --implicit-check-not=llvm.lifetime
+// RUN: %clang -target x86_64-linux-gnu -S -emit-llvm -o - -fno-exceptions -O0 \
+// RUN: -fsanitize=address -fsanitize-address-use-after-scope %s | \
+// RUN: FileCheck %s -check-prefixes=CHECK,CHECK-ASAN-USE-AFTER-SCOPE
+
+extern int bar(char *A, int n);
+
+struct X { X(); ~X(); int *p; };
+struct Y { Y(); int *p; };
+
+extern "C" void a(), b(), c(), d();
+
+// CHECK-LABEL: @_Z3foo
+void foo(int n) {
+ // CHECK: call void @a()
+ a();
+
+ // CHECK: call void @b()
+ // CHECK-ASAN-USE-AFTER-SCOPE: store i1 false
+ // CHECK-ASAN-USE-AFTER-SCOPE: store i1 false
+ // CHECK: br i1
+ //
+ // CHECK-ASAN-USE-AFTER-SCOPE: @llvm.lifetime.start
+ // CHECK-ASAN-USE-AFTER-SCOPE: store i1 true
+ // CHECK: call void @_ZN1XC
+ // CHECK: br label
+ //
+ // CHECK-ASAN-USE-AFTER-SCOPE: @llvm.lifetime.start
+ // CHECK-ASAN-USE-AFTER-SCOPE: store i1 true
+ // CHECK: call void @_ZN1YC
+ // CHECK: br label
+ //
+ // CHECK: call void @c()
+ // CHECK-ASAN-USE-AFTER-SCOPE: br i1
+ // CHECK-ASAN-USE-AFTER-SCOPE: @llvm.lifetime.end
+ // CHECK-ASAN-USE-AFTER-SCOPE: br i1
+ // CHECK-ASAN-USE-AFTER-SCOPE: @llvm.lifetime.end
+ b(), (n ? X().p : Y().p), c();
+
+ // CHECK: call void @d()
+ d();
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/linetable-cleanup.cpp b/src/llvm-project/clang/test/CodeGenCXX/linetable-cleanup.cpp
new file mode 100644
index 0000000..748f056
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/linetable-cleanup.cpp
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -triple x86_64-apple-darwin10 %s -o - | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -triple x86_64-apple-darwin10 -std=c++98 %s -o - | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -triple x86_64-apple-darwin10 -std=c++11 %s -o - | FileCheck %s
+
+// Check the line numbers for cleanup code with EH in combination with
+// simple return expressions.
+
+// CHECK: define {{.*}}foo
+// CHECK: call void @_ZN1CD1Ev(%class.C* {{.*}}){{( #[0-9])?}}, !dbg ![[RET:[0-9]+]]
+// CHECK: ret i32 0, !dbg ![[RET]]
+
+// CHECK: define {{.*}}bar
+// CHECK: ret void, !dbg ![[RETBAR:[0-9]+]]
+
+// CHECK: define {{.*}}baz
+// CHECK: ret void, !dbg ![[RETBAZ:[0-9]+]]
+
+class C {
+public:
+ ~C() {}
+ int i;
+};
+
+int foo()
+{
+ C c;
+ c.i = 42;
+ return 0;
+ // This breakpoint should be at/before the cleanup code.
+ // CHECK: ![[RET]] = !DILocation(line: [[@LINE+1]], scope: !{{.*}})
+}
+
+void bar()
+{
+ if (!foo())
+ // CHECK: {{.*}} = !DILocation(line: [[@LINE+1]], scope: !{{.*}})
+ return;
+
+ if (foo()) {
+ C c;
+ c.i = foo();
+ }
+ // Clang creates only a single ret instruction. Make sure it is at a useful line.
+ // CHECK: ![[RETBAR]] = !DILocation(line: [[@LINE+1]], scope: !{{.*}})
+}
+
+void baz()
+{
+ if (!foo())
+ // CHECK: ![[SCOPE1:.*]] = distinct !DILexicalBlock({{.*}}, line: [[@LINE-1]])
+ // CHECK: {{.*}} = !DILocation(line: [[@LINE+1]], scope: ![[SCOPE1]])
+ return;
+
+ if (foo()) {
+ // no cleanup
+ // CHECK: {{.*}} = !DILocation(line: [[@LINE+2]], scope: ![[SCOPE2:.*]])
+ // CHECK: ![[SCOPE2]] = distinct !DILexicalBlock({{.*}}, line: [[@LINE-3]])
+ return;
+ }
+ // CHECK: ![[RETBAZ]] = !DILocation(line: [[@LINE+1]], scope: !{{.*}})
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/linetable-eh.cpp b/src/llvm-project/clang/test/CodeGenCXX/linetable-eh.cpp
new file mode 100644
index 0000000..b31df54
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/linetable-eh.cpp
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -triple x86_64-apple-macosx10.9.0 -munwind-tables -std=c++11 -fcxx-exceptions -fexceptions %s -o - | FileCheck -allow-deprecated-dag-overlap %s
+
+// Test that emitting a landing pad does not affect the line table
+// entries for the code that triggered it.
+
+// CHECK: call void @llvm.dbg.declare
+// CHECK: call void @llvm.dbg.declare(metadata {{.*}}, metadata ![[CURRENT_ADDR:.*]], metadata !{{.*}}), !dbg ![[DBG1:.*]]
+// CHECK: unwind label %{{.*}}, !dbg ![[DBG1]]
+// CHECK: store i64 %{{.*}}, i64* %current_address, align 8, !dbg ![[DBG4:.*]]
+// CHECK-NEXT: call void @llvm.dbg.declare(metadata {{.*}}, metadata ![[FOUND_IT:.*]], metadata !{{.*}}), !dbg ![[DBG2:.*]]
+// CHECK: = landingpad
+// CHECK-NEXT: cleanup, !dbg ![[DBG3:.*]]
+// CHECK-DAG: ![[CURRENT_ADDR]] = {{.*}}name: "current_address"
+// CHECK-DAG: ![[FOUND_IT]] = {{.*}}name: "found_it"
+// CHECK-DAG: ![[DBG1]] = !DILocation(line: 256,
+// CHECK-DAG: ![[DBG2]] = !DILocation(line: 257,
+// CHECK-DAG: ![[DBG3]] = !DILocation(line: 268,
+// CHECK-DAG: ![[DBG4]] = !DILocation(line: 256,
+typedef unsigned long long uint64_t;
+template<class _Tp> class shared_ptr {
+public:
+ typedef _Tp element_type;
+ element_type* __ptr_;
+ ~shared_ptr();
+ element_type* operator->() const noexcept {return __ptr_;}
+};
+class Context {
+public:
+ uint64_t GetIt();
+};
+class Foo
+{
+ bool bar();
+ virtual shared_ptr<Context> GetContext () = 0;
+};
+# 253 "Foo.cpp" 3
+bool
+Foo::bar ()
+{
+ uint64_t current_address = GetContext()->GetIt();
+ bool found_it = false;
+# 267 "Foo.cpp" 3
+ return found_it;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/linetable-fnbegin.cpp b/src/llvm-project/clang/test/CodeGenCXX/linetable-fnbegin.cpp
new file mode 100644
index 0000000..3b93d70
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/linetable-fnbegin.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited %s -o - | FileCheck %s
+// Test that the line table info for Foo<T>::bar() is pointing to the
+// right header file.
+// CHECK: define{{.*}}bar
+// CHECK-NOT: define
+// CHECK: ret {{.*}}, !dbg [[DBG:.*]]
+// CHECK: [[HPP:.*]] = !DIFile(filename: "./template.hpp",
+// CHECK: [[SP:.*]] = distinct !DISubprogram(name: "bar",
+// CHECK-SAME: file: [[HPP]], line: 22
+// CHECK-SAME: DISPFlagDefinition
+// We shouldn't need a lexical block for this function.
+// CHECK: [[DBG]] = !DILocation(line: 23, scope: [[SP]])
+
+
+# 1 "./template.h" 1
+template <typename T>
+class Foo {
+public:
+ int bar();
+};
+# 21 "./template.hpp"
+template <typename T>
+int Foo<T>::bar() {
+ return 23;
+}
+int main (int argc, const char * argv[])
+{
+ Foo<int> f;
+ return f.bar();
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/linetable-virtual-variadic.cpp b/src/llvm-project/clang/test/CodeGenCXX/linetable-virtual-variadic.cpp
new file mode 100644
index 0000000..60dee5f
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/linetable-virtual-variadic.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -debug-info-kind=line-tables-only %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -debug-info-kind=line-directives-only %s -o - | FileCheck %s
+// Crasher for PR22929.
+class Base {
+ virtual void VariadicFunction(...);
+};
+
+class Derived : public virtual Base {
+ virtual void VariadicFunction(...);
+};
+
+void Derived::VariadicFunction(...) { }
+
+// CHECK: define void @_ZN7Derived16VariadicFunctionEz({{.*}} !dbg ![[SP:[0-9]+]]
+// CHECK: ret void, !dbg ![[LOC:[0-9]+]]
+// CHECK: define void @_ZT{{.+}}N7Derived16VariadicFunctionEz({{.*}} !dbg ![[SP_I:[0-9]+]]
+// CHECK: ret void, !dbg ![[LOC_I:[0-9]+]]
+//
+// CHECK: ![[SP]] = distinct !DISubprogram(name: "VariadicFunction"
+// CHECK: ![[LOC]] = !DILocation({{.*}}scope: ![[SP]])
+// CHECK: ![[SP_I]] = distinct !DISubprogram(name: "VariadicFunction"
+// CHECK: ![[LOC_I]] = !DILocation({{.*}}scope: ![[SP_I]])
diff --git a/src/llvm-project/clang/test/CodeGenCXX/linkage.cpp b/src/llvm-project/clang/test/CodeGenCXX/linkage.cpp
new file mode 100644
index 0000000..69b4262
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/linkage.cpp
@@ -0,0 +1,230 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -std=c++11 -O1 -disable-llvm-passes %s -o - | FileCheck %s
+
+namespace test1 {
+ // CHECK-DAG: define linkonce_odr void @_ZN5test11fIZNS_1gEvE1SEEvT_(
+ template <typename T> void f(T) {}
+ inline void *g() {
+ struct S {
+ } s;
+ return reinterpret_cast<void *>(f<S>);
+ }
+ void *h() { return g(); }
+}
+
+namespace test2 {
+ // CHECK-DAG: define internal void @_ZN5test21fIZNS_L1gEvE1SEEvT_(
+ template <typename T> void f(T) {}
+ static inline void *g() {
+ struct S {
+ } s;
+ return reinterpret_cast<void *>(f<S>);
+ }
+ void *h() { return g(); }
+}
+
+namespace test3 {
+ // CHECK-DAG: define internal void @_ZN5test31fIZNS_1gEvE1SEEvT_(
+ template <typename T> void f(T) {}
+ void *g() {
+ struct S {
+ } s;
+ return reinterpret_cast<void *>(f<S>);
+ }
+ void *h() { return g(); }
+}
+
+namespace test4 {
+ // CHECK-DAG: define linkonce_odr void @_ZN5test41fIZNS_1gILi1EEEPvvE1SEEvT_(
+ template <typename T> void f(T) {}
+ template <int N> inline void *g() {
+ struct S {
+ } s;
+ return reinterpret_cast<void *>(f<S>);
+ }
+ extern template void *g<1>();
+ template void *g<1>();
+}
+
+namespace test5 {
+ // CHECK-DAG: define linkonce_odr void @_ZN5test51fIZNS_1gILi1EEEPvvE1SEEvT_(
+ template <typename T> void f(T) {}
+ template <int N> inline void *g() {
+ struct S {
+ } s;
+ return reinterpret_cast<void *>(f<S>);
+ }
+ extern template void *g<1>();
+ void *h() { return g<1>(); }
+}
+
+namespace test6 {
+ // CHECK-DAG: define linkonce_odr void @_ZN5test61fIZZNS_1gEvEN1S1hEvE1TEEvv(
+ template <typename T> void f() {}
+
+ inline void *g() {
+ struct S {
+ void *h() {
+ struct T {
+ };
+ return (void *)f<T>;
+ }
+ } s;
+ return s.h();
+ }
+
+ void *h() { return g(); }
+}
+
+namespace test7 {
+ // CHECK-DAG: define internal void @_ZN5test71fIZZNS_1gEvEN1S1hEvE1TEEvv(
+ template <typename T> void f() {}
+
+ void *g() {
+ struct S {
+ void *h() {
+ struct T {
+ };
+ return (void *)f<T>;
+ }
+ } s;
+ return s.h();
+ }
+
+ void *h() { return g(); }
+}
+
+namespace test8 {
+ // CHECK-DAG: define linkonce_odr void @_ZN5test81fIZNS_1gEvE1SEEvT_(
+ template <typename T> void f(T) {}
+ inline void *g() {
+ enum S {
+ };
+ return reinterpret_cast<void *>(f<S>);
+ }
+ void *h() { return g(); }
+}
+
+namespace test9 {
+ // CHECK-DAG: define linkonce_odr void @_ZN5test91fIPZNS_1gEvE1SEEvT_(
+ template <typename T> void f(T) {}
+ inline void *g() {
+ struct S {
+ } s;
+ return reinterpret_cast<void *>(f<S*>);
+ }
+ void *h() { return g(); }
+}
+
+namespace test10 {
+ // CHECK-DAG: define linkonce_odr void @_ZN6test101fIPFZNS_1gEvE1SvEEEvT_(
+ template <typename T> void f(T) {}
+ inline void *g() {
+ struct S {
+ } s;
+ typedef S(*ftype)();
+ return reinterpret_cast<void *>(f<ftype>);
+ }
+ void *h() { return g(); }
+}
+
+namespace test11 {
+ // CHECK-DAG: define internal void @_ZN6test111fIPFZNS_1gEvE1SPNS_12_GLOBAL__N_11IEEEEvT_(
+ namespace {
+ struct I {
+ };
+ }
+
+ template <typename T> void f(T) {}
+ inline void *g() {
+ struct S {
+ };
+ typedef S(*ftype)(I * x);
+ return reinterpret_cast<void *>(f<ftype>);
+ }
+ void *h() { return g(); }
+}
+
+namespace test12 {
+ // CHECK-DAG: define linkonce_odr void @_ZN6test123fooIZNS_3barIZNS_3zedEvE2S2EEPvvE2S1EEvv
+ template <typename T> void foo() {}
+ template <typename T> inline void *bar() {
+ enum S1 {
+ };
+ return reinterpret_cast<void *>(foo<S1>);
+ }
+ inline void *zed() {
+ enum S2 {
+ };
+ return reinterpret_cast<void *>(bar<S2>);
+ }
+ void *h() { return zed(); }
+}
+
+namespace test13 {
+ // CHECK-DAG: define linkonce_odr void @_ZZN6test133fooEvEN1S3barEv(
+ inline void *foo() {
+ struct S {
+ static void bar() {}
+ };
+ return (void *)S::bar;
+ }
+ void *zed() { return foo(); }
+}
+
+namespace test14 {
+ // CHECK-DAG: define linkonce_odr void @_ZN6test143fooIZNS_1fEvE1SE3barILPS1_0EEEvv(
+ template <typename T> struct foo {
+ template <T *P> static void bar() {}
+ static void *g() { return (void *)bar<nullptr>; }
+ };
+ inline void *f() {
+ struct S {
+ };
+ return foo<S>::g();
+ }
+ void h() { f(); }
+}
+
+namespace test15 {
+ // CHECK-DAG: define linkonce_odr void @_ZN6test153zedIZNS_3fooIiEEPvvE3barEEvv(
+ template <class T> void zed() {}
+ template <class T> void *foo() {
+ class bar {
+ };
+ return reinterpret_cast<void *>(zed<bar>);
+ }
+ void test() { foo<int>(); }
+}
+
+namespace test16 {
+ // CHECK-DAG: define linkonce_odr void @_ZN6test163zedIZNS_3fooIiE3barEvE1SEEvv(
+ template <class T> void zed() {}
+ template <class T> struct foo {
+ static void *bar();
+ };
+ template <class T> void *foo<T>::bar() {
+ class S {
+ };
+ return reinterpret_cast<void *>(zed<S>);
+ }
+ void *test() { return foo<int>::bar(); }
+}
+
+namespace test17 {
+ // CHECK-DAG: @_ZZN6test173fooILi42EEEPivE3bar = linkonce_odr
+ // CHECK-DAG: define weak_odr i32* @_ZN6test173fooILi42EEEPiv(
+ template<int I>
+ int *foo() {
+ static int bar;
+ return &bar;
+ }
+ template int *foo<42>();
+}
+
+// PR18408
+namespace test18 {
+ template<template<typename> class> struct A {};
+ struct B { template<typename> struct C; };
+ void f(A<B::C>) {}
+ // CHECK-DAG: define void @_ZN6test181fENS_1AINS_1B1CEEE(
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/lpad-linetable.cpp b/src/llvm-project/clang/test/CodeGenCXX/lpad-linetable.cpp
new file mode 100644
index 0000000..9b429bc
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/lpad-linetable.cpp
@@ -0,0 +1,69 @@
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -emit-llvm -debug-info-kind=limited -triple x86_64-apple-darwin10 -std=c++98 %s -o - | FileCheck %s
+// The landing pad should have the line number of the closing brace of the function.
+// rdar://problem/13888152
+// CHECK: ret i32
+// CHECK: landingpad {{.*}}
+// CHECK-NEXT: !dbg ![[LPAD:[0-9]+]]
+// CHECK: ![[LPAD]] = !DILocation(line: 24, scope: !{{.*}})
+
+# 1 "/usr/include/c++/4.2.1/vector" 1 3
+typedef long unsigned int __darwin_size_t;
+typedef __darwin_size_t size_t;
+namespace std {
+ template<typename _Tp>
+ class allocator
+ {
+ public:
+ template<typename _Tp1>
+ struct rebind
+ { typedef allocator<_Tp1> other; };
+ ~allocator() throw() { }
+ };
+ template<typename _Tp, typename _Alloc>
+ struct _Vector_base
+ {
+ typedef typename _Alloc::template rebind<_Tp>::other _Tp_alloc_type;
+ struct _Vector_impl
+ {
+ _Vector_impl(_Tp_alloc_type const& __a) { }
+ };
+ typedef _Alloc allocator_type;
+ _Vector_base(const allocator_type& __a)
+ : _M_impl(__a)
+ { }
+ ~_Vector_base() { }
+ _Vector_impl _M_impl;
+ };
+ template<typename _Tp, typename _Alloc = std::allocator<_Tp> >
+ class vector
+ : protected _Vector_base<_Tp, _Alloc>
+ {
+ typedef _Vector_base<_Tp, _Alloc> _Base;
+ public:
+ typedef _Tp value_type;
+ typedef size_t size_type;
+ typedef _Alloc allocator_type;
+ vector(const allocator_type& __a = allocator_type())
+ : _Base(__a)
+ { }
+ size_type
+ push_back(const value_type& __x)
+ {}
+ };
+}
+# 10 "main.cpp" 2
+
+
+
+
+int main (int argc, char const *argv[], char const *envp[])
+{ // 15
+ std::vector<long> longs;
+ std::vector<short> shorts;
+ for (int i=0; i<12; i++)
+ {
+ longs.push_back(i);
+ shorts.push_back(i);
+ }
+ return 0; // 23
+} // 24
diff --git a/src/llvm-project/clang/test/CodeGenCXX/lto-visibility-inference.cpp b/src/llvm-project/clang/test/CodeGenCXX/lto-visibility-inference.cpp
new file mode 100644
index 0000000..8e57ef5
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/lto-visibility-inference.cpp
@@ -0,0 +1,107 @@
+// RUN: %clang_cc1 -flto -triple x86_64-unknown-linux -std=c++11 -fms-extensions -fvisibility hidden -fwhole-program-vtables -emit-llvm -o - %s | FileCheck --check-prefix=ITANIUM %s
+// RUN: %clang_cc1 -flto -triple x86_64-pc-windows-msvc -std=c++11 -fms-extensions -fwhole-program-vtables -emit-llvm -o - %s | FileCheck --check-prefix=MS --check-prefix=MS-STD %s
+// RUN: %clang_cc1 -flto -triple x86_64-pc-windows-msvc -std=c++11 -fms-extensions -fwhole-program-vtables -flto-visibility-public-std -emit-llvm -o - %s | FileCheck --check-prefix=MS --check-prefix=MS-NOSTD %s
+
+struct C1 {
+ virtual void f();
+};
+
+struct __attribute__((visibility("default"))) C2 {
+ virtual void f();
+};
+
+struct __declspec(dllexport) C3 {
+ virtual void f();
+};
+
+struct __declspec(dllimport) C4 {
+ virtual void f();
+};
+
+struct [[clang::lto_visibility_public]] C5 {
+ virtual void f();
+};
+
+struct __declspec(uuid("00000000-0000-0000-0000-000000000000")) C6 {
+ virtual void f();
+};
+
+namespace std {
+
+struct C7 {
+ virtual void f();
+ struct C8 {
+ virtual void f();
+ };
+};
+
+}
+
+extern "C++" {
+
+namespace stdext {
+
+struct C9 {
+ virtual void f();
+};
+
+}
+
+}
+
+namespace other {
+
+struct C10 {
+ virtual void f();
+};
+
+}
+
+namespace {
+
+struct C11 {
+ virtual void f();
+};
+
+}
+
+void f(C1 *c1, C2 *c2, C3 *c3, C4 *c4, C5 *c5, C6 *c6, std::C7 *c7,
+ std::C7::C8 *c8, stdext::C9 *c9, other::C10 *c10) {
+ // ITANIUM: type.test{{.*}}!"_ZTS2C1"
+ // MS: type.test{{.*}}!"?AUC1@@"
+ c1->f();
+ // ITANIUM-NOT: type.test{{.*}}!"_ZTS2C2"
+ // MS: type.test{{.*}}!"?AUC2@@"
+ c2->f();
+ // ITANIUM: type.test{{.*}}!"_ZTS2C3"
+ // MS-NOT: type.test{{.*}}!"?AUC3@@"
+ c3->f();
+ // ITANIUM: type.test{{.*}}!"_ZTS2C4"
+ // MS-NOT: type.test{{.*}}!"?AUC4@@"
+ c4->f();
+ // ITANIUM-NOT: type.test{{.*}}!"_ZTS2C5"
+ // MS-NOT: type.test{{.*}}!"?AUC5@@"
+ c5->f();
+ // ITANIUM-NOT: type.test{{.*}}!"_ZTS2C6"
+ // MS-NOT: type.test{{.*}}!"?AUC6@@"
+ c6->f();
+ // ITANIUM: type.test{{.*}}!"_ZTSSt2C7"
+ // MS-STD: type.test{{.*}}!"?AUC7@std@@"
+ // MS-NOSTD-NOT: type.test{{.*}}!"?AUC7@std@@"
+ c7->f();
+ // ITANIUM: type.test{{.*}}!"_ZTSNSt2C72C8E"
+ // MS-STD: type.test{{.*}}!"?AUC8@C7@std@@"
+ // MS-NOSTD-NOT: type.test{{.*}}!"?AUC8@C7@std@@"
+ c8->f();
+ // ITANIUM: type.test{{.*}}!"_ZTSN6stdext2C9E"
+ // MS-STD: type.test{{.*}}!"?AUC9@stdext@@"
+ // MS-NOSTD-NOT: type.test{{.*}}!"?AUC9@stdext@@"
+ c9->f();
+ // ITANIUM: type.test{{.*}}!"_ZTSN5other3C10E"
+ // MS: type.test{{.*}}!"?AUC10@other@@"
+ c10->f();
+ // ITANIUM: type.test{{.*}}!{{[0-9]}}
+ // MS: type.test{{.*}}!{{[0-9]}}
+ C11 *c11;
+ c11->f();
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/lvalue-bitcasts.cpp b/src/llvm-project/clang/test/CodeGenCXX/lvalue-bitcasts.cpp
new file mode 100644
index 0000000..c9997bf
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/lvalue-bitcasts.cpp
@@ -0,0 +1,163 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -emit-llvm -o - %s | FileCheck %s
+
+struct X { int i; float f; };
+struct Y { X x; };
+
+// CHECK-LABEL: define void @_Z21reinterpret_cast_testRiRfR1X
+void reinterpret_cast_test(int &ir, float &fr, X &xr) {
+ // CHECK: load float*, float**
+ // CHECK: bitcast float*
+ // CHECK: load i32, i32*
+ ir = reinterpret_cast<int&>(fr);
+ // CHECK: load
+ // CHECK: {{bitcast.*to i32\*}}
+ // CHECK: load i32, i32*
+ ir = reinterpret_cast<int&>(xr);
+ // CHECK: load i32
+ // CHECK: {{bitcast.*to float\*}}
+ // CHECK: load float, float*
+ fr = reinterpret_cast<float&>(ir);
+ // CHECK: load
+ // CHECK: {{bitcast.*to float\*}}
+ // CHECK: load float, float*
+ fr = reinterpret_cast<float&>(xr);
+ // CHECK: load i32*, i32**
+ // CHECK: bitcast i32*
+ // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
+ xr = reinterpret_cast<X&>(ir);
+ // CHECK: load float*, float**
+ // CHECK: bitcast float*
+ // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
+ xr = reinterpret_cast<X&>(fr);
+ _Complex float cf;
+ _Complex float &cfr = cf;
+ // CHECK: load i32*, i32**
+ // CHECK: bitcast i32*
+ // CHECK: load float, float*
+ // CHECK: load float, float*
+ cfr = reinterpret_cast<_Complex float&>(ir);
+ // CHECK: load float*, float**
+ // CHECK: bitcast float*
+ // CHECK: load float, float*
+ // CHECK: load float, float*
+ cfr = reinterpret_cast<_Complex float&>(fr);
+ // CHECK: bitcast
+ // CHECK: load float, float*
+ // CHECK: load float, float*
+ cfr = reinterpret_cast<_Complex float&>(xr);
+ // CHECK: ret void
+}
+
+// CHECK-LABEL: define void @_Z6c_castRiRfR1X
+void c_cast(int &ir, float &fr, X &xr) {
+ // CHECK: load float*, float**
+ // CHECK: bitcast float*
+ // CHECK: load i32, i32*
+ ir = (int&)fr;
+ // CHECK: load
+ // CHECK: {{bitcast.*to i32\*}}
+ // CHECK: load i32, i32*
+ ir = (int&)xr;
+ // CHECK: load i32
+ // CHECK: {{bitcast.*to float\*}}
+ // CHECK: load float, float*
+ fr = (float&)ir;
+ // CHECK: load
+ // CHECK: {{bitcast.*to float\*}}
+ // CHECK: load float, float*
+ fr = (float&)xr;
+ // CHECK: load i32*, i32**
+ // CHECK: bitcast i32*
+ // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
+ xr = (X&)ir;
+ // CHECK: load float*, float**
+ // CHECK: bitcast float*
+ // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
+ xr = (X&)fr;
+ _Complex float cf;
+ _Complex float &cfr = cf;
+ // CHECK: load i32*, i32**
+ // CHECK: bitcast i32*
+ // CHECK: load float, float*
+ // CHECK: load float, float*
+ cfr = (_Complex float&)ir;
+ // CHECK: load float*, float**
+ // CHECK: bitcast float*
+ // CHECK: load float, float*
+ // CHECK: load float, float*
+ cfr = (_Complex float&)fr;
+ // CHECK: bitcast
+ // CHECK: load float, float*
+ // CHECK: load float, float*
+ cfr = (_Complex float&)xr;
+ // CHECK: ret void
+}
+
+// CHECK-LABEL: define void @_Z15functional_castRiRfR1X
+void functional_cast(int &ir, float &fr, X &xr) {
+ typedef int &intref;
+ typedef float &floatref;
+ typedef X &Xref;
+ // CHECK: load float*, float**
+ // CHECK: bitcast float*
+ // CHECK: load i32, i32*
+ ir = intref(fr);
+ // CHECK: load
+ // CHECK: {{bitcast.*to i32\*}}
+ // CHECK: load i32, i32*
+ ir = intref(xr);
+ // CHECK: load i32
+ // CHECK: {{bitcast.*to float\*}}
+ // CHECK: load float, float*
+ fr = floatref(ir);
+ // CHECK: load
+ // CHECK: {{bitcast.*to float\*}}
+ // CHECK: load float, float*
+ fr = floatref(xr);
+ // CHECK: load i32*, i32**
+ // CHECK: bitcast i32*
+ // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
+ xr = Xref(ir);
+ // CHECK: load float*, float**
+ // CHECK: bitcast float*
+ // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
+ xr = Xref(fr);
+ typedef _Complex float &complex_float_ref;
+ _Complex float cf;
+ _Complex float &cfr = cf;
+ // CHECK: load i32*, i32**
+ // CHECK: bitcast i32*
+ // CHECK: load float, float*
+ // CHECK: load float, float*
+ cfr = complex_float_ref(ir);
+ // CHECK: load float*, float**
+ // CHECK: bitcast float*
+ // CHECK: load float, float*
+ // CHECK: load float, float*
+ cfr = complex_float_ref(fr);
+ // CHECK: bitcast
+ // CHECK: load float, float*
+ // CHECK: load float, float*
+ cfr = complex_float_ref(xr);
+ // CHECK: ret void
+}
+
+namespace PR6437 {
+ struct in_addr {};
+ void copy( const struct in_addr &new_addr ) {
+ int addr = (int&)new_addr;
+ }
+}
+
+namespace PR7593 {
+ void foo(double &X, char *A) {
+ X = reinterpret_cast<double&>(A[4]);
+ }
+}
+
+namespace PR7344 {
+ void serialize_annotatable_id( void*& id )
+ {
+ unsigned long l_id = (unsigned long&)id;
+ }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/m64-ptr.cpp b/src/llvm-project/clang/test/CodeGenCXX/m64-ptr.cpp
new file mode 100644
index 0000000..50ba6ae
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/m64-ptr.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 %s -emit-llvm -triple x86_64-apple-darwin -o - | FileCheck %s
+
+// Make sure pointers are passed as pointers, not converted to int.
+// The first load should be of type i8** in either 32 or 64 bit mode.
+// This formerly happened on x86-64, 7375899.
+
+class StringRef {
+public:
+ const char *Data;
+ long Len;
+};
+void foo(StringRef X);
+void bar(StringRef &A) {
+// CHECK: @_Z3barR9StringRef
+// CHECK: load i8*, i8**
+ foo(A);
+// CHECK: ret void
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/main-norecurse.cpp b/src/llvm-project/clang/test/CodeGenCXX/main-norecurse.cpp
new file mode 100644
index 0000000..a98677c
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/main-norecurse.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
+
+// CHECK: define {{.*}} @main({{.*}}) #0
+int main(int argc, char **argv) {
+ return 1;
+}
+
+// CHECK: attributes #0 = { noinline norecurse{{.*}} }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-98.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-98.cpp
new file mode 100644
index 0000000..a329caf
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-98.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -std=c++98 | FileCheck %s
+
+template <bool B> struct S3 {};
+
+// CHECK-LABEL: define void @_Z1f2S3ILb1EE
+void f(S3<true>) {}
+
+// CHECK-LABEL: define void @_Z1f2S3ILb0EE
+void f(S3<false>) {}
+
+// CHECK-LABEL: define void @_Z2f22S3ILb1EE
+void f2(S3<100>) {}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-abi-examples.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-abi-examples.cpp
new file mode 100644
index 0000000..832956f
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-abi-examples.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 %s -emit-llvm -triple %itanium_abi_triple -o - | FileCheck %s
+
+// CHECK: @_ZTVZN1A3fooEiE1B =
+// CHECK: @_ZTVZ3foovEN1C1DE =
+// 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/src/llvm-project/clang/test/CodeGenCXX/mangle-abi-tag.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-abi-tag.cpp
new file mode 100644
index 0000000..5d84096
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-abi-tag.cpp
@@ -0,0 +1,234 @@
+// RUN: %clang_cc1 %s -emit-llvm -triple %itanium_abi_triple -std=c++11 -o - | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -triple i686-linux-gnu -std=c++11 -o - | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -triple x86_64-linux-gnu -std=c++11 -o - | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -triple powerpc64le-unknown-linux-gnu -std=c++11 -o - | FileCheck %s
+
+struct __attribute__((abi_tag("A", "B"))) A { };
+
+struct B: A { };
+
+template<class T>
+
+struct C {
+};
+
+struct D { A* p; };
+
+template<class T>
+struct __attribute__((abi_tag("C", "D"))) E {
+};
+
+struct __attribute__((abi_tag("A", "B"))) F { };
+
+A a1;
+// CHECK-DAG: @_Z2a1B1AB1B =
+
+__attribute__((abi_tag("C", "D")))
+A a2;
+// CHECK-DAG: @_Z2a2B1AB1BB1CB1D =
+
+B a3;
+// CHECK-DAG: @a3 =
+
+C<A> a4;
+// CHECK-DAG: @_Z2a4B1AB1B =
+
+D a5;
+// CHECK-DAG: @a5 =
+
+E<int> a6;
+// CHECK-DAG: @_Z2a6B1CB1D =
+
+E<A> a7;
+// CHECK-DAG: @_Z2a7B1AB1BB1CB1D =
+
+template<>
+struct E<float> {
+ static float a8;
+};
+float E<float>::a8;
+// CHECK-DAG: @_ZN1EB1CB1DIfE2a8E =
+
+template<>
+struct E<F> {
+ static bool a9;
+};
+bool E<F>::a9;
+// CHECK-DAG: @_ZN1EB1CB1DI1FB1AB1BE2a9E =
+
+struct __attribute__((abi_tag("A", "B"))) A10 {
+ virtual ~A10() {}
+} a10;
+// vtable
+// CHECK-DAG: @_ZTV3A10B1AB1B =
+// typeinfo
+// CHECK-DAG: @_ZTI3A10B1AB1B =
+
+struct __attribute__((abi_tag("A"))) B11 {
+ static A10 b;
+};
+A10 B11::b;
+// B11[abi:A]::b[abi:B]
+// CHECK-DAG: @_ZN3B11B1A1bB1BE =
+
+__attribute__ ((abi_tag("C", "D")))
+void* f1() {
+ return 0;
+}
+// CHECK-DAG: define {{.*}} @_Z2f1B1CB1Dv(
+
+__attribute__ ((abi_tag("C", "D")))
+A* f2() {
+ return 0;
+}
+// CHECK-DAG: define {{.*}} @_Z2f2B1AB1BB1CB1Dv(
+
+B* f3() {
+ return 0;
+}
+// CHECK-DAG: define {{.*}} @_Z2f3v(
+
+C<A>* f4() {
+ return 0;
+}
+// CHECK-DAG: define {{.*}} @_Z2f4B1AB1Bv(
+
+D* f5() {
+ return 0;
+}
+// CHECK-DAG: define {{.*}} @_Z2f5v(
+
+E<char>* f6() {
+ return 0;
+}
+// CHECK-DAG: define {{.*}} @_Z2f6B1CB1Dv(
+
+E<A>* f7() {
+ return 0;
+}
+// CHECK-DAG: define {{.*}} @_Z2f7B1AB1BB1CB1Dv(
+
+void f8(E<A>*) {
+}
+// CHECK-DAG: define {{.*}} @_Z2f8P1EB1CB1DI1AB1AB1BE(
+
+inline namespace Names1 __attribute__((__abi_tag__)) {
+ class C1 {};
+}
+C1 f9() { return C1(); }
+// CHECK-DAG: @_Z2f9B6Names1v(
+
+inline namespace Names2 __attribute__((__abi_tag__("Tag1", "Tag2"))) {
+ class C2 {};
+}
+C2 f10() { return C2(); }
+// CHECK-DAG: @_Z3f10B4Tag1B4Tag2v(
+
+void __attribute__((abi_tag("A"))) f11(A) {}
+// f11[abi:A](A[abi:A][abi:B])
+// CHECK-DAG: define {{.*}} @_Z3f11B1A1AB1AB1B(
+
+A f12(A) { return A(); }
+// f12(A[abi:A][abi:B])
+// CHECK-DAG: define {{.*}} @_Z3f121AB1AB1B(
+
+inline void f13() {
+ struct L {
+ static E<int>* foo() {
+ static A10 a;
+ return 0;
+ }
+ };
+ L::foo();
+}
+void f13_test() {
+ f13();
+}
+// f13()::L::foo[abi:C][abi:D]()
+// CHECK-DAG: define linkonce_odr {{(dso_local )?}}%struct.E* @_ZZ3f13vEN1L3fooB1CB1DEv(
+
+// f13()::L::foo[abi:C][abi:D]()::a[abi:A][abi:B]
+// CHECK-DAG: @_ZZZ3f13vEN1L3fooB1CB1DEvE1aB1AB1B =
+
+// guard variable for f13()::L::foo[abi:C][abi:D]()::a[abi:A][abi:B]
+// CHECK-DAG: @_ZGVZZ3f13vEN1L3fooB1CB1DEvE1aB1AB1B =
+
+struct __attribute__((abi_tag("TAG"))) A14 {
+ A14 f14();
+};
+A14 A14::f14() {
+ return A14();
+}
+// A14[abi:TAG]::f14()
+// CHECK-DAG: define {{.+}} @_ZN3A14B3TAG3f14Ev(
+
+template<class T>
+T f15() {
+ return T();
+}
+void f15_test() {
+ f15<A14>();
+}
+// A14[abi:TAG] f15<A14[abi:TAG]>()
+// CHECK-DAG: define linkonce_odr {{.+}} @_Z3f15I3A14B3TAGET_v(
+
+template<class T>
+A14 f16() {
+ return A14();
+}
+void f16_test() {
+ f16<int>();
+}
+// A14[abi:TAG] f16<int>()
+// CHECK-DAG: define linkonce_odr {{.+}} @_Z3f16IiE3A14B3TAGv(
+
+template<class T>
+struct __attribute__((abi_tag("TAG"))) A17 {
+ A17 operator+(const A17& a) {
+ return a;
+ }
+};
+void f17_test() {
+ A17<int> a, b;
+ a + b;
+}
+// A17[abi:TAG]<int>::operator+(A17[abi:TAG]<int> const&)
+// CHECK-DAG: define linkonce_odr {{.+}} @_ZN3A17B3TAGIiEplERKS0_(
+
+struct A18 {
+ operator A() { return A(); }
+};
+void f18_test() {
+ A a = A18();
+}
+// A18::operator A[abi:A][abi:B]() but GCC adds the same tags twice!
+// CHECK-DAG: define linkonce_odr {{.+}} @_ZN3A18cv1AB1AB1BEv(
+
+namespace N19 {
+ class A {};
+ class __attribute__((abi_tag("B"))) B {};
+ class D {};
+ class F {};
+
+ template<typename T, B F(T, D)>
+ class C {};
+
+ B foo(A, D);
+}
+void f19_test(N19::C<N19::A, &N19::foo>, N19::F, N19::D) {
+}
+// f19_test(N19::C<N19::A, &N19::foo[abi:B]>, N19::F, N19::D)
+// CHECK-DAG: define {{(dso_local )?}}void @_Z8f19_testN3N191CINS_1AEXadL_ZNS_3fooB1BES1_NS_1DEEEEENS_1FES2_(
+
+namespace pr30440 {
+
+template<class F> void g(F);
+template<class ...A> auto h(A ...a)->decltype (g (0, g < a > (a) ...)) {
+}
+// CHECK-DAG: define {{.*}} @_ZN7pr304401hIJEEEDTcl1gLi0Espcl1gIL_ZZNS_1hEDpT_E1aEEfp_EEES2_(
+
+void pr30440_test () {
+ h();
+}
+
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-address-space.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-address-space.cpp
new file mode 100644
index 0000000..549ae54
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-address-space.cpp
@@ -0,0 +1,64 @@
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -o - %s | FileCheck %s --check-prefixes=CHECK,CHECKNOOCL
+// RUN: %clang_cc1 -emit-llvm -triple x86_64-windows-msvc -o - %s | FileCheck %s --check-prefixes=WIN,WINNOOCL
+// RUN: %clang_cc1 -cl-std=c++ -emit-llvm -triple %itanium_abi_triple -o - %s | FileCheck %s --check-prefixes=CHECK,CHECKOCL
+// RUN: %clang_cc1 -cl-std=c++ -emit-llvm -triple x86_64-windows-msvc -o - %s | FileCheck %s --check-prefixes=WIN,WINOCL
+
+// CHECKNOOCL-LABEL: define {{.*}}void @_Z2f0Pc
+// WINNOOCL-LABEL: define {{.*}}void @"?f0@@YAXPEAD@Z"
+// CHECKOCL-LABEL: define {{.*}}void @_Z2f0PU9CLgenericc
+// WINOCL-LABEL: define {{.*}}void @"?f0@@YAXPEAU?$_ASCLgeneric@$$CAD@__clang@@@Z"
+void f0(char *p) { }
+// CHECK-LABEL: define {{.*}}void @_Z2f0PU3AS1c
+// WIN-LABEL: define {{.*}}void @"?f0@@YAXPEAU?$_AS@$00$$CAD@__clang@@@Z"
+void f0(char __attribute__((address_space(1))) *p) { }
+
+struct OpaqueType;
+typedef OpaqueType __attribute__((address_space(100))) * OpaqueTypePtr;
+
+// CHECK-LABEL: define {{.*}}void @_Z2f0PU5AS10010OpaqueType
+// WIN-LABEL: define {{.*}}void @"?f0@@YAXPEAU?$_AS@$0GE@$$CAUOpaqueType@@@__clang@@@Z"
+void f0(OpaqueTypePtr) { }
+
+// CHECK-LABEL: define {{.*}}void @_Z2f1PU3AS1Kc
+// WIN-LABEL: define {{.*}}void @"?f1@@YAXPEAU?$_AS@$00$$CBD@__clang@@@Z"
+void f1(char __attribute__((address_space(1))) const *p) {}
+
+// Ensure we can do return values, which change in MS mode.
+// CHECK-LABEL: define {{.*}}float addrspace(1)* @_Z2f1PU3AS2Kc
+// WIN-LABEL: define {{.*}}float addrspace(1)* @"?f1@@YAPEAU?$_AS@$00$$CAM@__clang@@PEAU?$_AS@$01$$CBD@2@@Z"
+__attribute__((address_space(1))) float *f1(char __attribute__((address_space(2))) const *p) { return 0;}
+
+#if !defined(__OPENCL_CPP_VERSION__)
+// Return value of address space without a pointer is invalid in opencl.
+// Ensure we skip return values, since non-pointers aren't supposed to have an AS.
+// CHECKNOOCL-LABEL: define {{.*}}float @_Z2f2PU3AS2Kc
+// WINNOOCL-LABEL: define {{.*}}float @"?f2@@YA?AMQEAU?$_AS@$01$$CBD@__clang@@@Z"
+__attribute__((address_space(1))) float f2(char __attribute__((address_space(2))) const * const p) { return 0;}
+#endif
+
+#ifdef __OPENCL_CPP_VERSION__
+// CHECKOCL-LABEL: define {{.*}}void @_Z6ocl_f0PU9CLprivatec
+// WINOCL-LABEL: define {{.*}}void @"?ocl_f0@@YAXPEAU?$_ASCLprivate@$$CAD@__clang@@@Z"
+void ocl_f0(char __private *p) { }
+
+struct ocl_OpaqueType;
+typedef ocl_OpaqueType __global * ocl_OpaqueTypePtr;
+
+// CHECKOCL-LABEL: define {{.*}}void @_Z6ocl_f0PU8CLglobal14ocl_OpaqueType
+// WINOCL-LABEL: define {{.*}}void @"?ocl_f0@@YAXPEAU?$_ASCLglobal@$$CAUocl_OpaqueType@@@__clang@@@Z"
+void ocl_f0(ocl_OpaqueTypePtr) { }
+
+// CHECKOCL-LABEL: define {{.*}}void @_Z6ocl_f1PU10CLconstantKc
+// WINOCL-LABEL: define {{.*}}void @"?ocl_f1@@YAXPEAU?$_ASCLconstant@$$CBD@__clang@@@Z"
+void ocl_f1(char __constant const *p) {}
+
+// Ensure we can do return values, which change in MS mode.
+// CHECKOCL-LABEL: define {{.*}}float* @_Z6ocl_f1PU9CLgenericKc
+// WINOCL-LABEL: define {{.*}}float* @"?ocl_f1@@YAPEAU?$_ASCLconstant@$$CAM@__clang@@PEAU?$_ASCLgeneric@$$CBD@2@@Z"
+__constant float *ocl_f1(char __generic const *p) { return 0;}
+
+// Ensure we skip return values, since non-pointers aren't supposed to have an AS.
+// CHECKOCL-LABEL: define {{.*}}float* @_Z6ocl_f2PU9CLgenericKc
+// WINOCL-LABEL: define {{.*}}float* @"?ocl_f2@@YAPEAU?$_ASCLgeneric@$$CAM@__clang@@QEAU?$_ASCLgeneric@$$CBD@2@@Z"
+__generic float *ocl_f2(__generic char const * const p) { return 0;}
+#endif
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-alias-template.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-alias-template.cpp
new file mode 100644
index 0000000..1dbb3eb
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-alias-template.cpp
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
+
+template<typename T> struct alloc {};
+template<typename T> using Alloc = alloc<T>;
+template<typename T, typename A = Alloc<T>> struct vector {};
+
+template<typename T> using Vec = vector<T>;
+
+template<typename T> void f(Vec<T> v);
+template<typename T> void g(T);
+
+template<template<typename> class F> void h(F<int>);
+
+// CHECK-LABEL: define void @_Z1zv(
+void z() {
+ vector<int> VI;
+ f(VI);
+ // CHECK: call void @_Z1fIiEv6vectorIT_5allocIS1_EE(
+
+ Vec<double> VD;
+ g(VD);
+ // CHECK: call void @_Z1gI6vectorId5allocIdEEEvT_(
+
+ h<Vec>(VI);
+ // CHECK: call void @_Z1hI3VecEvT_IiE(
+
+ Alloc<int> AC;
+ h(AC);
+ // CHECK: call void @_Z1hI5allocEvT_IiE(
+
+ h<Alloc>(AC);
+ // CHECK: call void @_Z1hI5AllocEvT_IiE(
+
+ Vec<char> VC;
+ g<Vec<char>>(VC);
+ // CHECK: call void @_Z1gI6vectorIc5allocIcEEEvT_(
+
+ Vec<Vec<int>> VVI;
+ g(VVI);
+ // CHECK: call void @_Z1gI6vectorIS0_Ii5allocIiEES1_IS3_EEEvT_(
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-exception-spec.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-exception-spec.cpp
new file mode 100644
index 0000000..15f7a8b
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-exception-spec.cpp
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -Wno-dynamic-exception-spec | FileCheck %s --check-prefix CHECK --check-prefix CHECK-CXX11
+// RUN: %clang_cc1 -std=c++1z -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -Wno-dynamic-exception-spec | FileCheck %s --check-prefix CHECK --check-prefix CHECK-CXX17
+
+// CHECK: define {{.*}} @_Z1aPFivE(
+void a(int() throw(int, float)) {}
+// CHECK-CXX11: define {{.*}} @_Z1bPFivE(
+// CHECK-CXX17: define {{.*}} @_Z1bPDoFivE(
+void b(int() noexcept) {}
+// CHECK-CXX11: define {{.*}} @_Z1cPFivE(
+// CHECK-CXX17: define {{.*}} @_Z1cPDoFivE(
+void c(int() throw()) {}
+// CHECK: define {{.*}} @_Z1dPFivE(
+void d(int() noexcept(false)) {}
+// CHECK-CXX11: define {{.*}} @_Z1ePFivE(
+// CHECK-CXX17: define {{.*}} @_Z1ePDoFivE(
+void e(int() noexcept(true)) {}
+
+template<bool B> void f(int() noexcept(B)) {}
+// CHECK: define {{.*}} @_Z1fILb0EEvPDOT_EFivE(
+template void f<false>(int());
+// CHECK: define {{.*}} @_Z1fILb1EEvPDOT_EFivE(
+template void f<true>(int() noexcept);
+
+template<typename...T> void g(int() throw(T...)) {}
+// CHECK: define {{.*}} @_Z1gIJEEvPDwDpT_EFivE(
+template void g<>(int() noexcept);
+// CHECK: define {{.*}} @_Z1gIJfEEvPDwDpT_EFivE(
+template void g<float>(int());
+
+// We consider the exception specifications in parameter and return type here
+// to be different.
+template<typename...T> auto h(int() throw(int, T...)) -> int (*)() throw(T..., int) { return nullptr; }
+// CHECK: define {{.*}} @_Z1hIJEEPDwDpT_iEFivEPDwiS1_EFivE(
+template auto h<>(int()) -> int (*)();
+// CHECK: define {{.*}} @_Z1hIJfEEPDwDpT_iEFivEPDwiS1_EFivE(
+template auto h<float>(int()) -> int (*)();
+
+// FIXME: The C++11 manglings here are wrong; they should be the same as the
+// C++17 manglings.
+// The mangler mishandles substitutions for instantiation-dependent types that
+// differ only in type sugar that is not relevant for mangling. (In this case,
+// the types differ in presence/absence of ParenType nodes under the pointer.)
+template<typename...T> auto i(int() throw(int, T...)) -> int (*)() throw(int, T...) { return nullptr; }
+// CHECK-CXX11: define {{.*}} @_Z1iIJEEPDwiDpT_EFivEPS2_(
+// CHECK-CXX17: define {{.*}} @_Z1iIJEEPDwiDpT_EFivES3_(
+template auto i<>(int()) -> int (*)();
+// CHECK-CXX11: define {{.*}} @_Z1iIJfEEPDwiDpT_EFivEPS2_(
+// CHECK-CXX17: define {{.*}} @_Z1iIJfEEPDwiDpT_EFivES3_(
+template auto i<float>(int()) -> int (*)();
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-exprs.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-exprs.cpp
new file mode 100644
index 0000000..6c46402
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-exprs.cpp
@@ -0,0 +1,375 @@
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s
+
+namespace std {
+ typedef decltype(sizeof(int)) size_t;
+
+ // libc++'s implementation
+ template <class _E>
+ class initializer_list
+ {
+ const _E* __begin_;
+ size_t __size_;
+
+ initializer_list(const _E* __b, size_t __s)
+ : __begin_(__b),
+ __size_(__s)
+ {}
+
+ public:
+ typedef _E value_type;
+ typedef const _E& reference;
+ typedef const _E& const_reference;
+ typedef size_t size_type;
+
+ typedef const _E* iterator;
+ typedef const _E* const_iterator;
+
+ initializer_list() : __begin_(nullptr), __size_(0) {}
+
+ size_t size() const {return __size_;}
+ const _E* begin() const {return __begin_;}
+ const _E* end() const {return __begin_ + __size_;}
+ };
+}
+
+template < bool condition, typename T = void >
+struct enable_if { typedef T type; };
+
+template< typename T >
+struct enable_if< false, T > {};
+
+// PR5876
+namespace Casts {
+ template< unsigned O >
+ void implicit(typename enable_if< O <= 4 >::type* = 0) {
+ }
+
+ template< unsigned O >
+ void cstyle(typename enable_if< O <= (unsigned)4 >::type* = 0) {
+ }
+
+ template< unsigned O >
+ void functional(typename enable_if< O <= unsigned(4) >::type* = 0) {
+ }
+
+ template< unsigned O >
+ void static_(typename enable_if< O <= static_cast<unsigned>(4) >::type* = 0) {
+ }
+
+ template <unsigned O, typename T>
+ void reinterpret_(typename enable_if<O <= sizeof(reinterpret_cast<T *>(0))>::type * = 0) {
+ }
+
+ template <typename T, T *p>
+ void const_(typename enable_if<0 <= sizeof(const_cast<T *>(p))>::type * = 0) {
+ }
+
+ template <typename T, T *p>
+ void dynamic_(typename enable_if<0 <= sizeof(dynamic_cast<T *>(p))>::type * = 0) {
+ }
+
+ template< typename T >
+ void auto_(decltype(new auto(T()))) {
+ }
+
+ template< typename T >
+ void scalar_(decltype(T(), int())) {
+ }
+
+ template <unsigned N> struct T {};
+
+ template <int N> T<N> f() { return T<N>(); }
+
+ extern int i;
+ extern struct S {} s;
+
+ // CHECK-LABEL: define weak_odr void @_ZN5Casts8implicitILj4EEEvPN9enable_ifIXleT_Li4EEvE4typeE
+ template void implicit<4>(void*);
+ // CHECK-LABEL: define weak_odr void @_ZN5Casts6cstyleILj4EEEvPN9enable_ifIXleT_cvjLi4EEvE4typeE
+ template void cstyle<4>(void*);
+ // CHECK-LABEL: define weak_odr void @_ZN5Casts10functionalILj4EEEvPN9enable_ifIXleT_cvjLi4EEvE4typeE
+ template void functional<4>(void*);
+ // CHECK-LABEL: define weak_odr void @_ZN5Casts7static_ILj4EEEvPN9enable_ifIXleT_scjLi4EEvE4typeE
+ template void static_<4>(void*);
+ // CHECK-LABEL: define weak_odr void @_ZN5Casts12reinterpret_ILj4EiEEvPN9enable_ifIXleT_szrcPT0_Li0EEvE4typeE
+ template void reinterpret_<4, int>(void*);
+ // CHECK-LABEL: define weak_odr void @_ZN5Casts6const_IiXadL_ZNS_1iEEEEEvPN9enable_ifIXleLi0EszccPT_T0_EvE4typeE
+ template void const_<int, &i>(void*);
+ // CHECK-LABEL: define weak_odr void @_ZN5Casts8dynamic_INS_1SEXadL_ZNS_1sEEEEEvPN9enable_ifIXleLi0EszdcPT_T0_EvE4typeE
+ template void dynamic_<struct S, &s>(void*);
+
+ // CHECK-LABEL: define weak_odr void @_ZN5Casts1fILi6EEENS_1TIXT_EEEv
+ template T<6> f<6>();
+
+ // CHECK-LABEL: define weak_odr void @_ZN5Casts5auto_IiEEvDTnw_DapicvT__EEE(
+ template void auto_<int>(int*);
+
+ // CHECK-LABEL: define weak_odr void @_ZN5Casts7scalar_IiEEvDTcmcvT__Ecvi_EE(
+ template void scalar_<int>(int);
+}
+
+namespace test1 {
+ short foo(short);
+ int foo(int);
+
+ // CHECK-LABEL: define linkonce_odr signext i16 @_ZN5test11aIsEEDTcl3foocvT__EEES1_(
+ template <class T> auto a(T t) -> decltype(foo(T())) { return foo(t); }
+
+ // CHECK-LABEL: define linkonce_odr signext i16 @_ZN5test11bIsEEDTcp3foocvT__EEES1_(
+ template <class T> auto b(T t) -> decltype((foo)(T())) { return (foo)(t); }
+
+ void test(short s) {
+ a(s);
+ b(s);
+ }
+}
+
+namespace test2 {
+ template <class T> void a(T x, decltype(x()) y) {}
+ template <class T> auto b(T x) -> decltype(x()) { return x(); }
+ template <class T> void c(T x, void (*p)(decltype(x()))) {}
+ template <class T> void d(T x, auto (*p)() -> decltype(x())) {}
+ template <class T> void e(auto (*p)(T y) -> decltype(y())) {}
+ template <class T> void f(void (*p)(T x, decltype(x()) y)) {}
+ template <class T> void g(T x, decltype(x()) y) {
+ static decltype(x()) variable;
+ variable = 0;
+ }
+ template <class T> void h(T x, decltype((decltype(x())(*)()) 0) y) {}
+ template <class T> void i(decltype((auto (*)(T x) -> decltype(x())) 0) y) {}
+
+ float foo();
+ void bar(float);
+ float baz(float(*)());
+ void fred(float(*)(), float);
+
+ // CHECK-LABEL: define void @_ZN5test211instantiateEv
+ void instantiate() {
+ // CHECK: call void @_ZN5test21aIPFfvEEEvT_DTclfL0p_EE(
+ a(foo, 0.0f);
+ // CHECK: call float @_ZN5test21bIPFfvEEEDTclfp_EET_(
+ (void) b(foo);
+ // CHECK: call void @_ZN5test21cIPFfvEEEvT_PFvDTclfL1p_EEE(
+ c(foo, bar);
+ // CHECK: call void @_ZN5test21dIPFfvEEEvT_PFDTclfL0p_EEvE(
+ d(foo, foo);
+ // CHECK: call void @_ZN5test21eIPFfvEEEvPFDTclfp_EET_E(
+ e(baz);
+ // CHECK: call void @_ZN5test21fIPFfvEEEvPFvT_DTclfL0p_EEE(
+ f(fred);
+ // CHECK: call void @_ZN5test21gIPFfvEEEvT_DTclfL0p_EE(
+ g(foo, 0.0f);
+ // CHECK: call void @_ZN5test21hIPFfvEEEvT_DTcvPFDTclfL0p_EEvELi0EE(
+ h(foo, foo);
+ // CHECK: call void @_ZN5test21iIPFfvEEEvDTcvPFDTclfp_EET_ELi0EE(
+ i<float(*)()>(baz);
+ }
+
+ // CHECK: store float {{.*}}, float* @_ZZN5test21gIPFfvEEEvT_DTclfL0p_EEE8variable,
+}
+
+namespace test3 {
+ template <class T, class U> void a(T x, U y, decltype(x.*y) z) {}
+
+ struct X {
+ int *member;
+ };
+
+ // CHECK-LABEL: define void @_ZN5test311instantiateEv
+ void instantiate() {
+ X x;
+ int *ip;
+ // CHECK: call void @_ZN5test31aINS_1XEMS1_PiEEvT_T0_DTdsfL0p_fL0p0_E
+ a(x, &X::member, ip);
+ }
+}
+
+namespace test4 {
+ struct X {
+ X(int);
+ };
+
+ template <typename T>
+ void tf1(decltype(new T(1)) p)
+ {}
+
+ template <typename T>
+ void tf2(decltype(new T({1})) p)
+ {}
+
+ template <typename T>
+ void tf3(decltype(new T{1}) p)
+ {}
+
+ // CHECK: void @_ZN5test43tf1INS_1XEEEvDTnw_T_piLi1EEE
+ template void tf1<X>(X*);
+
+ // CHECK: void @_ZN5test43tf2INS_1XEEEvDTnw_T_piilLi1EEEE
+ template void tf2<X>(X*);
+
+ // CHECK: void @_ZN5test43tf3INS_1XEEEvDTnw_T_ilLi1EEE
+ template void tf3<X>(X*);
+
+}
+
+namespace test5 {
+ template <typename T> void a(decltype(noexcept(T()))) {}
+ template void a<int>(decltype(noexcept(int())));
+ // CHECK: void @_ZN5test51aIiEEvDTnxcvT__EE(
+}
+
+namespace test6 {
+ struct X {
+ int i;
+ };
+
+ struct Y {
+ union {
+ int i;
+ };
+ };
+
+ struct Z {
+ union {
+ X ua;
+ Y ub;
+ };
+
+ struct {
+ X s;
+ };
+
+ union {
+ union {
+ struct {
+ struct {
+ X uuss;
+ };
+ };
+ };
+ };
+ };
+
+ Z z, *zp;
+
+ template<typename T>
+ void f1(decltype(T(z.ua.i))) {}
+ template void f1<int>(int);
+ // CHECK-LABEL: define weak_odr void @_ZN5test62f1IiEEvDTcvT_dtdtL_ZNS_1zEE2ua1iE
+
+ template<typename T>
+ void f2(decltype(T(z.ub.i))) {}
+ template void f2<int>(int);
+ // CHECK-LABEL: define weak_odr void @_ZN5test62f2IiEEvDTcvT_dtdtL_ZNS_1zEE2ub1iE
+
+ template<typename T>
+ void f3(decltype(T(z.s.i))) {}
+ template void f3<int>(int);
+ // CHECK-LABEL: define weak_odr void @_ZN5test62f3IiEEvDTcvT_dtdtL_ZNS_1zEE1s1iE
+
+ template<typename T>
+ void f4(decltype(T(z.uuss.i))) {}
+ template void f4<int>(int);
+ // CHECK-LABEL: define weak_odr void @_ZN5test62f4IiEEvDTcvT_dtdtL_ZNS_1zEE4uuss1iE
+
+ template<typename T>
+ void f5(decltype(T(zp->ua.i))) {}
+ template void f5<int>(int);
+ // CHECK-LABEL: define weak_odr void @_ZN5test62f5IiEEvDTcvT_dtptL_ZNS_2zpEE2ua1iE
+
+ template<typename T>
+ void f6(decltype(T(zp->ub.i))) {}
+ template void f6<int>(int);
+ // CHECK-LABEL: define weak_odr void @_ZN5test62f6IiEEvDTcvT_dtptL_ZNS_2zpEE2ub1iE
+
+ template<typename T>
+ void f7(decltype(T(zp->s.i))) {}
+ template void f7<int>(int);
+ // CHECK-LABEL: define weak_odr void @_ZN5test62f7IiEEvDTcvT_dtptL_ZNS_2zpEE1s1iE
+
+ template<typename T>
+ void f8(decltype(T(zp->uuss.i))) {}
+ template void f8<int>(int);
+ // CHECK-LABEL: define weak_odr void @_ZN5test62f8IiEEvDTcvT_dtptL_ZNS_2zpEE4uuss1iE
+}
+
+namespace test7 {
+ struct A { int x[3]; };
+ struct B { B(int, int); } extern b;
+ struct C { C(B); };
+ struct D { D(C); };
+ struct E { E(std::initializer_list<int>); };
+ struct F { F(E); };
+
+ template<class T> decltype(A{1,2},T()) fA1(T t) {}
+ template<class T> decltype(A({1,2}),T()) fA2(T t) {}
+ template<class T> decltype(B{1,2},T()) fB1(T t) {}
+ template<class T> decltype(B({1,2}),T()) fB2(T t) {}
+ template<class T> decltype(C{{1,2}},T()) fC1(T t) {}
+ template<class T> decltype(C({1,2}),T()) fC2(T t) {}
+ template<class T> decltype(D{b},T()) fD1(T t) {}
+ template<class T> decltype(D(b),T()) fD2(T t) {}
+ template<class T> decltype(E{1,2},T()) fE1(T t) {}
+ template<class T> decltype(E({1,2}),T()) fE2(T t) {}
+ template<class T> decltype(F{{1,2}},T()) fF1(T t) {}
+ template<class T> decltype(F({1,2}),T()) fF2(T t) {}
+
+ template<class T> decltype(T{}) fT1(T t) {}
+ template<class T> decltype(T()) fT2(T t) {}
+ template<class T> decltype(T{1}) fT3(T t) {}
+ template<class T> decltype(T(1)) fT4(T t) {}
+ template<class T> decltype(T{1,2}) fT5(T t) {}
+ template<class T> decltype(T(1,2)) fT6(T t) {}
+ template<class T> decltype(T{{}}) fT7(T t) {}
+ template<class T> decltype(T({})) fT8(T t) {}
+ template<class T> decltype(T{{1}}) fT9(T t) {}
+ template<class T> decltype(T({1})) fTA(T t) {}
+ template<class T> decltype(T{{1,2}}) fTB(T t) {}
+ template<class T> decltype(T({1,2})) fTC(T t) {}
+
+ int main() {
+ fA1(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fA1IiEEDTcmtlNS_1AELi1ELi2EEcvT__EES2_
+ fA2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fA2IiEEDTcmcvNS_1AEilLi1ELi2EEcvT__EES2_
+ fB1(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fB1IiEEDTcmtlNS_1BELi1ELi2EEcvT__EES2_
+ fB2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fB2IiEEDTcmcvNS_1BEilLi1ELi2EEcvT__EES2_
+ fC1(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fC1IiEEDTcmtlNS_1CEilLi1ELi2EEEcvT__EES2_
+ fC2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fC2IiEEDTcmcvNS_1CEilLi1ELi2EEcvT__EES2_
+ fD1(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fD1IiEEDTcmtlNS_1DEL_ZNS_1bEEEcvT__EES2_
+ fD2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fD2IiEEDTcmcvNS_1DEL_ZNS_1bEEcvT__EES2_
+ fE1(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fE1IiEEDTcmtlNS_1EELi1ELi2EEcvT__EES2_
+ fE2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fE2IiEEDTcmcvNS_1EEilLi1ELi2EEcvT__EES2_
+ fF1(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fF1IiEEDTcmtlNS_1FEilLi1ELi2EEEcvT__EES2_
+ fF2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fF2IiEEDTcmcvNS_1FEilLi1ELi2EEcvT__EES2_
+ fT1(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fT1IiEEDTtlT_EES1_(
+ fT2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fT2IiEEDTcvT__EES1_(
+ fT3(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fT3IiEEDTtlT_Li1EEES1_(
+ fT4(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fT4IiEEDTcvT_Li1EES1_(
+ fT5(b); // CHECK-LABEL: define {{.*}} @_ZN5test73fT5INS_1BEEEDTtlT_Li1ELi2EEES2_(
+ fT6(b); // CHECK-LABEL: define {{.*}} @_ZN5test73fT6INS_1BEEEDTcvT__Li1ELi2EEES2_(
+ fT7(A{}); // CHECK-LABEL: define {{.*}} @_ZN5test73fT7INS_1AEEEDTtlT_ilEEES2_(
+ fT8(A{}); // CHECK-LABEL: define {{.*}} @_ZN5test73fT8INS_1AEEEDTcvT_ilEES2_(
+ fT9(A{}); // CHECK-LABEL: define {{.*}} @_ZN5test73fT9INS_1AEEEDTtlT_ilLi1EEEES2_(
+ fTA(A{}); // CHECK-LABEL: define {{.*}} @_ZN5test73fTAINS_1AEEEDTcvT_ilLi1EEES2_(
+ fTB<C>(b); // CHECK-LABEL: define {{.*}} @_ZN5test73fTBINS_1CEEEDTtlT_ilLi1ELi2EEEES2_(
+ fTC<C>(b); // CHECK-LABEL: define {{.*}} @_ZN5test73fTCINS_1CEEEDTcvT_ilLi1ELi2EEES2_(
+ }
+}
+
+
+namespace test8 {
+ template <class>
+ struct X {
+ template<typename T> T foo() const { return 0; }
+ template <class T> auto bar() const -> decltype(foo<T>()) { return 0; }
+ };
+
+ // CHECK-LABEL: define weak_odr i32 @_ZNK5test81XIiE3barIiEEDTcl3fooIT_EEEv
+ template int X<int>::bar<int>() const;
+}
+
+namespace designated_init {
+ struct A { struct B { int b[5][5]; } a; };
+ // CHECK-LABEL: define {{.*}} @_ZN15designated_init1fINS_1AEEEvDTtlT_di1adi1bdxLi3EdXLi1ELi4ELi9EEE(
+ template<typename T> void f(decltype(T{.a.b[3][1 ... 4] = 9}) x) {}
+ void use_f(A a) { f<A>(a); }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-extern-local.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-extern-local.cpp
new file mode 100644
index 0000000..1394c8f
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-extern-local.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 %s -triple i386-unknown-unknown -emit-llvm -o - | FileCheck %s
+
+// CHECK: @var1 = external global i32
+// CHECK: @_ZN1N4var2E = external global i32
+// CHECK: @var5 = external global i32
+// CHECK: @_ZN1N4var3E = external global i32
+// CHECK: @_ZN1N4var4E = external global i32
+
+// CHECK: declare i32 @_Z5func1v()
+// CHECK: declare i32 @_ZN1N5func2Ev()
+// CHECK: declare i32 @func4()
+// CHECK: declare i32 @_ZN1N5func3Ev()
+
+int f1() {
+ extern int var1, func1();
+ return var1 + func1();
+}
+
+namespace N {
+
+int f2() {
+ extern int var2, func2();
+ return var2 + func2();
+}
+
+struct S {
+ static int f3() {
+ extern int var3, func3();
+ struct LC { int localfunc() { extern int var4; return var4; } };
+ LC localobj;
+ return var3 + func3() + localobj.localfunc();
+ }
+};
+
+int anchorf3() { return S::f3(); }
+
+extern "C" {
+int f4() {
+ extern int var5, func4();
+ return var5 + func4();
+}
+}
+
+}
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-extreme.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-extreme.cpp
new file mode 100644
index 0000000..9fa678a
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-extreme.cpp
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s
+
+struct X { };
+
+// CHECK-LABEL: define void @_Z1fPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP1XS13_S12_S11_S10_SZ_SY_SX_SW_SV_SU_ST_SS_SR_SQ_SP_SO_SN_SM_SL_SK_SJ_SI_SH_SG_SF_SE_SD_SC_SB_SA_S9_S8_S7_S6_S5_S4_S3_S2_S1_S0_S_(
+void f(X****************************************,
+ X****************************************,
+ X***************************************,
+ X**************************************,
+ X*************************************,
+ X************************************,
+ X***********************************,
+ X**********************************,
+ X*********************************,
+ X********************************,
+ X*******************************,
+ X******************************,
+ X*****************************,
+ X****************************,
+ X***************************,
+ X**************************,
+ X*************************,
+ X************************,
+ X***********************,
+ X**********************,
+ X*********************,
+ X********************,
+ X*******************,
+ X******************,
+ X*****************,
+ X****************,
+ X***************,
+ X**************,
+ X*************,
+ X************,
+ X***********,
+ X**********,
+ X*********,
+ X********,
+ X*******,
+ X******,
+ X*****,
+ X****,
+ X***,
+ X**,
+ X*,
+ X) { }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-fail.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-fail.cpp
new file mode 100644
index 0000000..b588d57
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-fail.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -emit-llvm-only -x c++ -std=c++11 -triple %itanium_abi_triple -verify %s -DN=1
+// RUN: %clang_cc1 -emit-llvm-only -x c++ -std=c++11 -triple %itanium_abi_triple -verify %s -DN=2
+
+struct A { int a; };
+
+#if N == 1
+// ChooseExpr
+template<class T> void test(int (&)[sizeof(__builtin_choose_expr(true, 1, 1), T())]) {} // expected-error {{cannot yet mangle}}
+template void test<int>(int (&)[sizeof(int)]);
+
+#elif N == 2
+// CompoundLiteralExpr
+template<class T> void test(int (&)[sizeof((A){}, T())]) {} // expected-error {{cannot yet mangle}}
+template void test<int>(int (&)[sizeof(A)]);
+
+// FIXME: There are several more cases we can't yet mangle.
+
+#else
+#error unknown N
+#endif
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-lambdas.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-lambdas.cpp
new file mode 100644
index 0000000..d49ed4b
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-lambdas.cpp
@@ -0,0 +1,272 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-macosx10.7.0 -emit-llvm -o - %s -w | FileCheck %s
+
+// CHECK-LABEL: define linkonce_odr void @_Z11inline_funci
+inline void inline_func(int n) {
+ // CHECK: call i32 @_ZZ11inline_funciENKUlvE_clEv
+ int i = []{ return 1; }();
+
+ // CHECK: call i32 @_ZZ11inline_funciENKUlvE0_clEv
+ int j = [=] { return n + i; }();
+
+ // CHECK: call double @_ZZ11inline_funciENKUlvE1_clEv
+ int k = [=] () -> double { return n + i; }();
+
+ // CHECK: call i32 @_ZZ11inline_funciENKUliE_clEi
+ int l = [=] (int x) -> int { return x + i; }(n);
+
+ int inner(int i = []{ return 17; }());
+ // CHECK: call i32 @_ZZ11inline_funciENKUlvE2_clEv
+ // CHECK-NEXT: call i32 @_Z5inneri
+ inner();
+
+ // CHECK-NEXT: ret void
+}
+
+void call_inline_func() {
+ inline_func(17);
+}
+
+// CHECK-LABEL: define linkonce_odr i32* @_ZNK10inline_varMUlvE_clEv(
+// CHECK: @_ZZNK10inline_varMUlvE_clEvE1n
+inline auto inline_var = [] {
+ static int n = 5;
+ return &n;
+};
+
+int *use_inline_var = inline_var();
+
+// CHECK-LABEL: define linkonce_odr i32* @_ZNK12var_templateIiEMUlvE_clEv(
+// CHECK: @_ZZNK12var_templateIiEMUlvE_clEvE1n
+template<typename T> auto var_template = [] {
+ static int n = 9;
+ return &n;
+};
+
+int *use_var_template = var_template<int>();
+
+struct S {
+ void f(int = []{return 1;}()
+ + []{return 2;}(),
+ int = []{return 3;}());
+ void g(int, int);
+};
+
+void S::g(int i = []{return 1;}(),
+ int j = []{return 2; }()) {}
+
+// CHECK-LABEL: define void @_Z6test_S1S
+void test_S(S s) {
+ // CHECK: call i32 @_ZZN1S1fEiiEd0_NKUlvE_clEv
+ // CHECK-NEXT: call i32 @_ZZN1S1fEiiEd0_NKUlvE0_clEv
+ // CHECK-NEXT: add nsw i32
+ // CHECK-NEXT: call i32 @_ZZN1S1fEiiEd_NKUlvE_clEv
+ // CHECK-NEXT: call void @_ZN1S1fEii
+ s.f();
+
+ // NOTE: These manglings don't actually matter that much, because
+ // the lambdas in the default arguments of g() won't be seen by
+ // multiple translation units. We check them mainly to ensure that they don't
+ // get the special mangling for lambdas in in-class default arguments.
+ // CHECK: call i32 @"_ZNK1S3$_0clEv"
+ // CHECK-NEXT: call i32 @"_ZNK1S3$_1clEv"
+ // CHECK-NEXT: call void @_ZN1S1gEi
+ s.g();
+
+ // CHECK-NEXT: ret void
+}
+
+// Check the linkage of the lambda call operators used in test_S.
+// CHECK-LABEL: define linkonce_odr i32 @_ZZN1S1fEiiEd0_NKUlvE_clEv
+// CHECK: ret i32 1
+// CHECK-LABEL: define linkonce_odr i32 @_ZZN1S1fEiiEd0_NKUlvE0_clEv
+// CHECK: ret i32 2
+// CHECK-LABEL: define linkonce_odr i32 @_ZZN1S1fEiiEd_NKUlvE_clEv
+// CHECK: ret i32 3
+// CHECK-LABEL: define internal i32 @"_ZNK1S3$_0clEv"
+// CHECK: ret i32 1
+// CHECK-LABEL: define internal i32 @"_ZNK1S3$_1clEv"
+// CHECK: ret i32 2
+
+template<typename T>
+struct ST {
+ void f(T = []{return T() + 1;}()
+ + []{return T() + 2;}(),
+ T = []{return T(3);}());
+};
+
+// CHECK-LABEL: define void @_Z7test_ST2STIdE
+void test_ST(ST<double> st) {
+ // CHECK: call double @_ZZN2STIdE1fEddEd0_NKUlvE_clEv
+ // CHECK-NEXT: call double @_ZZN2STIdE1fEddEd0_NKUlvE0_clEv
+ // CHECK-NEXT: fadd double
+ // CHECK-NEXT: call double @_ZZN2STIdE1fEddEd_NKUlvE_clEv
+ // CHECK-NEXT: call void @_ZN2STIdE1fEdd
+ st.f();
+
+ // CHECK-NEXT: ret void
+}
+
+// Check the linkage of the lambda call operators used in test_ST.
+// CHECK-LABEL: define linkonce_odr double @_ZZN2STIdE1fEddEd0_NKUlvE_clEv
+// CHECK: ret double 1
+// CHECK-LABEL: define linkonce_odr double @_ZZN2STIdE1fEddEd0_NKUlvE0_clEv
+// CHECK: ret double 2
+// CHECK-LABEL: define linkonce_odr double @_ZZN2STIdE1fEddEd_NKUlvE_clEv
+// CHECK: ret double 3
+
+template<typename T>
+struct StaticMembers {
+ static T x;
+ static T y;
+ static T z;
+ static int (*f)();
+};
+
+template<typename T> int accept_lambda(T);
+
+template<typename T>
+T StaticMembers<T>::x = []{return 1;}() + []{return 2;}();
+
+template<typename T>
+T StaticMembers<T>::y = []{return 3;}();
+
+template<typename T>
+T StaticMembers<T>::z = accept_lambda([]{return 4;});
+
+template<typename T>
+int (*StaticMembers<T>::f)() = []{return 5;};
+
+// CHECK-LABEL: define internal void @__cxx_global_var_init
+// CHECK: call i32 @_ZNK13StaticMembersIfE1xMUlvE_clEv
+// CHECK-NEXT: call i32 @_ZNK13StaticMembersIfE1xMUlvE0_clEv
+// CHECK-NEXT: add nsw
+// CHECK-LABEL: define linkonce_odr i32 @_ZNK13StaticMembersIfE1xMUlvE_clEv
+// CHECK: ret i32 1
+// CHECK-LABEL: define linkonce_odr i32 @_ZNK13StaticMembersIfE1xMUlvE0_clEv
+// CHECK: ret i32 2
+template float StaticMembers<float>::x;
+
+// CHECK-LABEL: define internal void @__cxx_global_var_init
+// CHECK: call i32 @_ZNK13StaticMembersIfE1yMUlvE_clEv
+// CHECK-LABEL: define linkonce_odr i32 @_ZNK13StaticMembersIfE1yMUlvE_clEv
+// CHECK: ret i32 3
+template float StaticMembers<float>::y;
+
+// CHECK-LABEL: define internal void @__cxx_global_var_init
+// CHECK: call i32 @_Z13accept_lambdaIN13StaticMembersIfE1zMUlvE_EEiT_
+// CHECK: declare i32 @_Z13accept_lambdaIN13StaticMembersIfE1zMUlvE_EEiT_()
+template float StaticMembers<float>::z;
+
+// CHECK-LABEL: define internal void @__cxx_global_var_init
+// CHECK: call {{.*}} @_ZNK13StaticMembersIfE1fMUlvE_cvPFivEEv
+// CHECK-LABEL: define linkonce_odr i32 ()* @_ZNK13StaticMembersIfE1fMUlvE_cvPFivEEv
+template int (*StaticMembers<float>::f)();
+
+// CHECK-LABEL: define internal void @__cxx_global_var_init
+// CHECK: call i32 @"_ZNK13StaticMembersIdE3$_2clEv"
+// CHECK-LABEL: define internal i32 @"_ZNK13StaticMembersIdE3$_2clEv"
+// CHECK: ret i32 42
+template<> double StaticMembers<double>::z = []{return 42; }();
+
+template<typename T>
+void func_template(T = []{ return T(); }());
+
+// CHECK-LABEL: define void @_Z17use_func_templatev()
+void use_func_template() {
+ // CHECK: call i32 @"_ZZ13func_templateIiEvT_ENK3$_3clEv"
+ func_template<int>();
+}
+
+namespace std {
+ struct type_info;
+}
+namespace PR12123 {
+ struct A { virtual ~A(); } g;
+ struct B {
+ void f(const std::type_info& x = typeid([]()->A& { return g; }()));
+ void h();
+ };
+ void B::h() { f(); }
+}
+
+// CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %"struct.PR12123::A"* @_ZZN7PR121231B1fERKSt9type_infoEd_NKUlvE_clEv
+
+// CHECK-LABEL: define {{.*}} @_Z{{[0-9]*}}testVarargsLambdaNumberingv(
+inline int testVarargsLambdaNumbering() {
+ // CHECK: testVarargsLambdaNumberingvE{{.*}}UlzE_
+ auto a = [](...) { static int n; return ++n; };
+ // CHECK: testVarargsLambdaNumberingvE{{.*}}UlvE_
+ auto b = []() { static int n; return ++n; };
+ return a() + b();
+}
+int k = testVarargsLambdaNumbering();
+
+// Check linkage of the various lambdas.
+// CHECK-LABEL: define linkonce_odr i32 @_ZZ11inline_funciENKUlvE_clEv
+// CHECK: ret i32 1
+// CHECK-LABEL: define linkonce_odr i32 @_ZZ11inline_funciENKUlvE0_clEv
+// CHECK: ret i32
+// CHECK-LABEL: define linkonce_odr double @_ZZ11inline_funciENKUlvE1_clEv
+// CHECK: ret double
+// CHECK-LABEL: define linkonce_odr i32 @_ZZ11inline_funciENKUliE_clEi
+// CHECK: ret i32
+// CHECK-LABEL: define linkonce_odr i32 @_ZZ11inline_funciENKUlvE2_clEv
+// CHECK: ret i32 17
+
+// CHECK-LABEL: define linkonce_odr void @_ZN7MembersC2Ev
+// CHECK: call i32 @_ZNK7Members1xMUlvE_clEv
+// CHECK-NEXT: call i32 @_ZNK7Members1xMUlvE0_clE
+// CHECK-NEXT: add nsw i32
+// CHECK: call i32 @_ZNK7Members1yMUlvE_clEv
+// CHECK: ret void
+
+
+// Check the linkage of the lambdas used in test_Members.
+// CHECK-LABEL: define linkonce_odr i32 @_ZNK7Members1xMUlvE_clEv
+// CHECK: ret i32 1
+// CHECK-LABEL: define linkonce_odr i32 @_ZNK7Members1xMUlvE0_clEv
+// CHECK: ret i32 2
+// CHECK-LABEL: define linkonce_odr i32 @_ZNK7Members1yMUlvE_clEv
+// CHECK: ret i32 3
+
+// CHECK-LABEL: define linkonce_odr void @_Z1fIZZNK23TestNestedInstantiationclEvENKUlvE_clEvEUlvE_EvT_
+
+
+namespace PR12808 {
+ template <typename> struct B {
+ int a;
+ template <typename L> constexpr B(L&& x) : a(x()) { }
+ };
+ template <typename> void b(int) {
+ [&]{ (void)B<int>([&]{ return 1; }); }();
+ }
+ void f() {
+ b<int>(1);
+ }
+ // CHECK-LABEL: define linkonce_odr void @_ZZN7PR128081bIiEEviENKUlvE_clEv
+ // CHECK-LABEL: define linkonce_odr i32 @_ZZZN7PR128081bIiEEviENKUlvE_clEvENKUlvE_clEv
+}
+
+
+struct Members {
+ int x = [] { return 1; }() + [] { return 2; }();
+ int y = [] { return 3; }();
+};
+
+void test_Members() {
+ Members members;
+}
+
+template<typename P> void f(P) { }
+
+struct TestNestedInstantiation {
+ void operator()() const {
+ []() -> void {
+ return f([]{});
+ }();
+ }
+};
+
+void test_NestedInstantiation() {
+ TestNestedInstantiation()();
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-literal-suffix.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-literal-suffix.cpp
new file mode 100644
index 0000000..d3ca9ff
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-literal-suffix.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -triple mips-none-none -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=FP64
+// RUN: %clang_cc1 -triple powerpc64-none-none -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=FP128
+
+template <class T> void g3(char (&buffer)[sizeof(T() + 5.0)]) {}
+template void g3<int>(char (&)[sizeof(double)]);
+// CHECK: _Z2g3IiEvRAszplcvT__ELd4014000000000000E_c
+
+template <class T> void g4(char (&buffer)[sizeof(T() + 5.0L)]) {}
+template void g4<int>(char (&)[sizeof(long double)]);
+// FP64: _Z2g4IiEvRAszplcvT__ELe4014000000000000E_c
+// FP128: _Z2g4IiEvRAszplcvT__ELg00000000000000004014000000000000E_c
+
+template <class T> void g5(char (&buffer)[sizeof(T() + 5)]) {}
+template void g5<int>(char (&)[sizeof(int)]);
+// CHECK: _Z2g5IiEvRAszplcvT__ELi5E_c
+
+template <class T> void g6(char (&buffer)[sizeof(T() + 5L)]) {}
+template void g6<int>(char (&)[sizeof(long int)]);
+// CHECK: _Z2g6IiEvRAszplcvT__ELl5E_c
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-local-anonymous-unions.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-local-anonymous-unions.cpp
new file mode 100644
index 0000000..9187c1a
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-local-anonymous-unions.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 %s -emit-llvm -triple %itanium_abi_triple -o - | FileCheck %s
+
+// CHECK-DAG: @_ZZ2f0vE1a
+// CHECK-DAG: @_ZZ2f0vE1c
+// CHECK-DAG: @_ZZ2f0vE1e_0
+inline int f0() {
+ static union {
+ int a;
+ long int b;
+ };
+
+ static union {
+ int c;
+ double d;
+ };
+
+ if (0) {
+ static union {
+ int e;
+ int f;
+ };
+ }
+ static union {
+ int e;
+ int f;
+ };
+
+ return a+c;
+}
+
+inline void nop() {
+ static union {
+ union {
+ };
+ };
+}
+
+int f1 (int a, int c) {
+ nop();
+ return a+c+f0();
+}
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-local-class-names.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-local-class-names.cpp
new file mode 100644
index 0000000..848e460
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-local-class-names.cpp
@@ -0,0 +1,87 @@
+// RUN: %clang_cc1 %s -emit-llvm -triple %itanium_abi_triple -o - | FileCheck %s
+
+// CHECK: @_ZZ4FUNCvEN4SSSSC1ERKf
+// CHECK: @_ZZ4FUNCvEN4SSSSC2E_0RKf
+// CHECK: @_ZZ4GORFfEN4SSSSC1ERKf
+// CHECK: @_ZZ4GORFfEN4SSSSC2E_0RKf
+
+void FUNC ()
+{
+ {
+ float IVAR1 ;
+
+ struct SSSS
+ {
+ float bv;
+ SSSS( const float& from): bv(from) { }
+ };
+
+ SSSS VAR1(IVAR1);
+ }
+
+ {
+ float IVAR2 ;
+
+ struct SSSS
+ {
+ SSSS( const float& from) {}
+ };
+
+ SSSS VAR2(IVAR2);
+ }
+}
+
+void GORF (float IVAR1)
+{
+ {
+ struct SSSS
+ {
+ float bv;
+ SSSS( const float& from): bv(from) { }
+ };
+
+ SSSS VAR1(IVAR1);
+ }
+
+ {
+ float IVAR2 ;
+
+ struct SSSS
+ {
+ SSSS( const float& from) {}
+ };
+
+ SSSS VAR2(IVAR2);
+ }
+}
+
+// CHECK: @_ZZ12OmittingCodefEN4SSSSC1E_0RKf
+inline void OmittingCode(float x) {
+ if (0) {
+ struct SSSS {
+ float bv;
+ SSSS(const float& from): bv(from) { }
+ };
+
+ SSSS VAR1(x);
+ }
+
+ struct SSSS {
+ float bv;
+ SSSS(const float& from): bv(from) { }
+ };
+
+ SSSS VAR2(x);
+}
+void CallOmittingCode() { OmittingCode(1); }
+
+// CHECK: @_ZZ15LocalAnonStructvENUt0_1gEv
+inline void LocalAnonStruct() {
+ if (0) {
+ struct { void f() {} } x;
+ x.f();
+ }
+ struct { void g() {} } y;
+ y.g();
+}
+void CallLocalAnonStruct() { LocalAnonStruct(); }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-local-class-vtables.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-local-class-vtables.cpp
new file mode 100644
index 0000000..c90353e
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-local-class-vtables.cpp
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 %s -emit-llvm -triple %itanium_abi_triple -o - | FileCheck %s
+
+// CHECK: @_ZTVZ1GvE1C = {{.*}} @_ZTIZ1GvE1C {{.*}} @_ZZ1GvENK1C1FEv
+// CHECK: @_ZTIZ1GvE1C = {{.*}} @_ZTSZ1GvE1C
+// CHECK: @_ZTVZ1GvE1C_0 = {{.*}} @_ZTIZ1GvE1C_0 {{.*}} @_ZZ1GvENK1C1FE_0v
+// CHECK: @_ZTIZ1GvE1C_0 = {{.*}} @_ZTSZ1GvE1C_0
+// CHECK: @_ZTVZ1GvE1C_1 = {{.*}} @_ZTIZ1GvE1C_1 {{.*}} @_ZZ1GvENK1C1FE_1v
+// CHECK: @_ZTIZ1GvE1C_1 = {{.*}} @_ZTSZ1GvE1C_1
+// CHECK: @_ZTVZN1J1KEvE1C = {{.*}} @_ZTIZN1J1KEvE1C {{.*}} @_ZZN1J1KEvENK1C1FEv
+// CHECK: @_ZTIZN1J1KEvE1C = {{.*}} @_ZTSZN1J1KEvE1C
+
+// CHECK: define {{.*}} @_ZZ1GvEN1CC2Ev(
+// CHECK: define {{.*}} @_ZZ1GvENK1C1FEv(
+// CHECK: define {{.*}} @_ZZ1GvEN1CC2E_0v(
+// CHECK: define {{.*}} @_ZZ1GvENK1C1FE_0v(
+// CHECK: define {{.*}} @_ZZ1GvENK1C1GE_0v(
+// CHECK: define {{.*}} @_ZZ1GvEN1CC2E_1v(
+// CHECK: define {{.*}} @_ZZ1GvENK1C1FE_1v(
+// CHECK: define {{.*}} @_ZZ1GvENK1C1HE_1v(
+// CHECK: define {{.*}} @_ZZN1J1KEvEN1CC2Ev(
+// CHECK: define {{.*}} @_ZZN1J1KEvENK1C1FEv(
+
+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/src/llvm-project/clang/test/CodeGenCXX/mangle-local-classes-nested.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-local-classes-nested.cpp
new file mode 100644
index 0000000..5daf0c0
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-local-classes-nested.cpp
@@ -0,0 +1,81 @@
+// RUN: %clang_cc1 %s -emit-llvm -triple %itanium_abi_triple -o - | FileCheck %s
+
+// CHECK: @_ZTVZZ1HvEN1S1IEvE1S =
+
+// CHECK: define {{.*}} @_Z2L1v(
+// CHECK: define {{.*}} @_ZZ2L1vEN1S2L2Ev(
+// CHECK: define {{.*}} @_ZZ2L1vEN1S2L2E_0v(
+// CHECK: define {{.*}} @_ZZ1FvEN1S1T1S1T1GEv(
+// CHECK: define {{.*}} @_ZZZ2L1vEN1S2L2EvEN1S3L3aEv(
+// CHECK: define {{.*}} @_ZZZ2L1vEN1S2L2EvEN1S3L3bE_0v(
+// CHECK: define {{.*}} @_ZZZ2L1vEN1S2L2E_0vEN1S3L3cEv(
+// CHECK: define {{.*}} @_ZZZ2L1vEN1S2L2E_0vEN1S3L3dE_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/src/llvm-project/clang/test/CodeGenCXX/mangle-long-double.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-long-double.cpp
new file mode 100644
index 0000000..177982b
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-long-double.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -triple powerpc64-unknown-linux-gnu %s -emit-llvm -o - | FileCheck %s --check-prefix=POWER64-LINUX
+// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu %s -emit-llvm -o - | FileCheck %s --check-prefix=POWER-LINUX
+// RUN: %clang_cc1 -triple s390x-unknown-linux-gnu %s -emit-llvm -o - | FileCheck %s --check-prefix=S390X-LINUX
+
+void f(long double) {}
+// POWER64-LINUX: _Z1fg
+// POWER-LINUX: _Z1fg
+// S390X-LINUX: _Z1fg
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-mingw.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-mingw.cpp
new file mode 100644
index 0000000..90a9826
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-mingw.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-w64-mingw32 | FileCheck %s
+
+int func() { return 0; }
+// CHECK-DAG: @_Z4funcv
+
+int main() { return 0; }
+// CHECK-DAG: @main
+
+int wmain() { return 0; }
+// CHECK-DAG: @wmain
+
+int WinMain() { return 0; }
+// CHECK-DAG: @WinMain
+
+int wWinMain() { return 0; }
+// CHECK-DAG: @wWinMain
+
+int DllMain() { return 0; }
+// CHECK-DAG: @DllMain
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-abi-examples.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-abi-examples.cpp
new file mode 100644
index 0000000..2f8490a
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-abi-examples.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -fms-extensions -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 -fms-compatibility-version=19.00 | FileCheck %s --check-prefix=CHECK --check-prefix=MSVC2015
+// RUN: %clang_cc1 -fms-extensions -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 -fms-compatibility-version=18.00 | FileCheck %s --check-prefix=CHECK --check-prefix=MSVC2013
+
+// CHECK: @"??_7B@?1??foo@A@@QAEXH@Z@6B@" =
+// CHECK: @"??_7D@C@?1??foo@@YAXXZ@6B@" =
+// MSVC2013: define {{.*}} @"?baz@E@?3??bar@C@?1??foo@@YAXXZ@QAEXXZ@QAEXXZ"(
+// MSVC2015: define {{.*}} @"?baz@E@?1??bar@C@?1??foo@@YAXXZ@QAEXXZ@QAEXXZ"(
+
+// Microsoft Visual C++ ABI examples.
+struct A {
+ void foo (int) {
+ struct B { virtual ~B() {} };
+ B();
+ }
+};
+inline void foo () {
+ struct C {
+ struct D { virtual ~D() {} };
+ void bar () {
+ struct E {
+ void baz() { }
+ };
+ E().baz();
+ }
+ };
+ A().foo(0);
+ C::D();
+ C().bar();
+}
+void call () {
+ foo();
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp
new file mode 100644
index 0000000..23582c6c
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp
@@ -0,0 +1,269 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-pc-win32 | FileCheck -check-prefix=X64 %s
+
+void foo(const unsigned int) {}
+// CHECK: "?foo@@YAXI@Z"
+// X64: "?foo@@YAXI@Z"
+
+void foo(const double) {}
+// CHECK: "?foo@@YAXN@Z"
+// X64: "?foo@@YAXN@Z"
+
+void bar(const volatile double) {}
+// CHECK: "?bar@@YAXN@Z"
+// X64: "?bar@@YAXN@Z"
+
+void foo_pad(char * x) {}
+// CHECK: "?foo_pad@@YAXPAD@Z"
+// X64: "?foo_pad@@YAXPEAD@Z"
+
+void foo_pbd(const char * x) {}
+// CHECK: "?foo_pbd@@YAXPBD@Z"
+// X64: "?foo_pbd@@YAXPEBD@Z"
+
+void foo_pcd(volatile char * x) {}
+// CHECK: "?foo_pcd@@YAXPCD@Z"
+// X64: "?foo_pcd@@YAXPECD@Z"
+
+void foo_qad(char * const x) {}
+// CHECK: "?foo_qad@@YAXQAD@Z"
+// X64: "?foo_qad@@YAXQEAD@Z"
+
+void foo_rad(char * volatile x) {}
+// CHECK: "?foo_rad@@YAXRAD@Z"
+// X64: "?foo_rad@@YAXREAD@Z"
+
+void foo_sad(char * const volatile x) {}
+// CHECK: "?foo_sad@@YAXSAD@Z"
+// X64: "?foo_sad@@YAXSEAD@Z"
+
+void foo_piad(char * __restrict x) {}
+// CHECK: "?foo_piad@@YAXPIAD@Z"
+// X64: "?foo_piad@@YAXPEIAD@Z"
+
+void foo_qiad(char * const __restrict x) {}
+// CHECK: "?foo_qiad@@YAXQIAD@Z"
+// X64: "?foo_qiad@@YAXQEIAD@Z"
+
+void foo_riad(char * volatile __restrict x) {}
+// CHECK: "?foo_riad@@YAXRIAD@Z"
+// X64: "?foo_riad@@YAXREIAD@Z"
+
+void foo_siad(char * const volatile __restrict x) {}
+// CHECK: "?foo_siad@@YAXSIAD@Z"
+// X64: "?foo_siad@@YAXSEIAD@Z"
+
+void foo_papad(char ** x) {}
+// CHECK: "?foo_papad@@YAXPAPAD@Z"
+// X64: "?foo_papad@@YAXPEAPEAD@Z"
+
+void foo_papbd(char const ** x) {}
+// CHECK: "?foo_papbd@@YAXPAPBD@Z"
+// X64: "?foo_papbd@@YAXPEAPEBD@Z"
+
+void foo_papcd(char volatile ** x) {}
+// CHECK: "?foo_papcd@@YAXPAPCD@Z"
+// X64: "?foo_papcd@@YAXPEAPECD@Z"
+
+void foo_pbqad(char * const* x) {}
+// CHECK: "?foo_pbqad@@YAXPBQAD@Z"
+// X64: "?foo_pbqad@@YAXPEBQEAD@Z"
+
+void foo_pcrad(char * volatile* x) {}
+// CHECK: "?foo_pcrad@@YAXPCRAD@Z"
+// X64: "?foo_pcrad@@YAXPECREAD@Z"
+
+void foo_qapad(char ** const x) {}
+// CHECK: "?foo_qapad@@YAXQAPAD@Z"
+// X64: "?foo_qapad@@YAXQEAPEAD@Z"
+
+void foo_rapad(char ** volatile x) {}
+// CHECK: "?foo_rapad@@YAXRAPAD@Z"
+// X64: "?foo_rapad@@YAXREAPEAD@Z"
+
+void foo_pbqbd(const char * const* x) {}
+// CHECK: "?foo_pbqbd@@YAXPBQBD@Z"
+// X64: "?foo_pbqbd@@YAXPEBQEBD@Z"
+
+void foo_pbqcd(volatile char * const* x) {}
+// CHECK: "?foo_pbqcd@@YAXPBQCD@Z"
+// X64: "?foo_pbqcd@@YAXPEBQECD@Z"
+
+void foo_pcrbd(const char * volatile* x) {}
+// CHECK: "?foo_pcrbd@@YAXPCRBD@Z"
+// X64: "?foo_pcrbd@@YAXPECREBD@Z"
+
+void foo_pcrcd(volatile char * volatile* x) {}
+// CHECK: "?foo_pcrcd@@YAXPCRCD@Z"
+// X64: "?foo_pcrcd@@YAXPECRECD@Z"
+
+void foo_aad(char &x) {}
+// CHECK: "?foo_aad@@YAXAAD@Z"
+// X64: "?foo_aad@@YAXAEAD@Z"
+
+void foo_abd(const char &x) {}
+// CHECK: "?foo_abd@@YAXABD@Z"
+// X64: "?foo_abd@@YAXAEBD@Z"
+
+void foo_aapad(char *&x) {}
+// CHECK: "?foo_aapad@@YAXAAPAD@Z"
+// X64: "?foo_aapad@@YAXAEAPEAD@Z"
+
+void foo_aapbd(const char *&x) {}
+// CHECK: "?foo_aapbd@@YAXAAPBD@Z"
+// X64: "?foo_aapbd@@YAXAEAPEBD@Z"
+
+void foo_abqad(char * const &x) {}
+// CHECK: "?foo_abqad@@YAXABQAD@Z"
+// X64: "?foo_abqad@@YAXAEBQEAD@Z"
+
+void foo_abqbd(const char * const &x) {}
+// CHECK: "?foo_abqbd@@YAXABQBD@Z"
+// X64: "?foo_abqbd@@YAXAEBQEBD@Z"
+
+void foo_aay144h(int (&x)[5][5]) {}
+// CHECK: "?foo_aay144h@@YAXAAY144H@Z"
+// X64: "?foo_aay144h@@YAXAEAY144H@Z"
+
+void foo_aay144cbh(const int (&x)[5][5]) {}
+// CHECK: "?foo_aay144cbh@@YAXAAY144$$CBH@Z"
+// X64: "?foo_aay144cbh@@YAXAEAY144$$CBH@Z"
+
+void foo_qay144h(int (&&x)[5][5]) {}
+// CHECK: "?foo_qay144h@@YAX$$QAY144H@Z"
+// X64: "?foo_qay144h@@YAX$$QEAY144H@Z"
+
+void foo_qay144cbh(const int (&&x)[5][5]) {}
+// CHECK: "?foo_qay144cbh@@YAX$$QAY144$$CBH@Z"
+// X64: "?foo_qay144cbh@@YAX$$QEAY144$$CBH@Z"
+
+void foo_p6ahxz(int x()) {}
+// CHECK: "?foo_p6ahxz@@YAXP6AHXZ@Z"
+// X64: "?foo_p6ahxz@@YAXP6AHXZ@Z"
+
+void foo_a6ahxz(int (&x)()) {}
+// CHECK: "?foo_a6ahxz@@YAXA6AHXZ@Z"
+// X64: "?foo_a6ahxz@@YAXA6AHXZ@Z"
+
+void foo_q6ahxz(int (&&x)()) {}
+// CHECK: "?foo_q6ahxz@@YAX$$Q6AHXZ@Z"
+// X64: "?foo_q6ahxz@@YAX$$Q6AHXZ@Z"
+
+void foo_qay04h(int x[5][5]) {}
+// CHECK: "?foo_qay04h@@YAXQAY04H@Z"
+// X64: "?foo_qay04h@@YAXQEAY04H@Z"
+
+void foo_qay04cbh(const int x[5][5]) {}
+// CHECK: "?foo_qay04cbh@@YAXQAY04$$CBH@Z"
+// X64: "?foo_qay04cbh@@YAXQEAY04$$CBH@Z"
+
+typedef double Vector[3];
+
+void foo(Vector*) {}
+// CHECK: "?foo@@YAXPAY02N@Z"
+// X64: "?foo@@YAXPEAY02N@Z"
+
+void foo(Vector) {}
+// CHECK: "?foo@@YAXQAN@Z"
+// X64: "?foo@@YAXQEAN@Z"
+
+void foo_const(const Vector) {}
+// CHECK: "?foo_const@@YAXQBN@Z"
+// X64: "?foo_const@@YAXQEBN@Z"
+
+void foo_volatile(volatile Vector) {}
+// CHECK: "?foo_volatile@@YAXQCN@Z"
+// X64: "?foo_volatile@@YAXQECN@Z"
+
+void foo(Vector*, const Vector, const double) {}
+// CHECK: "?foo@@YAXPAY02NQBNN@Z"
+// X64: "?foo@@YAXPEAY02NQEBNN@Z"
+
+typedef void (*ConstFunPtr)(int *const d);
+void foo_fnptrconst(ConstFunPtr f) { }
+// CHECK: "?foo_fnptrconst@@YAXP6AXQAH@Z@Z"
+// X64: "?foo_fnptrconst@@YAXP6AXQEAH@Z@Z"
+
+typedef void (*ArrayFunPtr)(int d[1]);
+void foo_fnptrarray(ArrayFunPtr f) { }
+// CHECK: "?foo_fnptrarray@@YAXP6AXQAH@Z@Z"
+// X64: "?foo_fnptrarray@@YAXP6AXQEAH@Z@Z"
+
+void foo_fnptrbackref1(ArrayFunPtr f1, ArrayFunPtr f2) { }
+// CHECK: "?foo_fnptrbackref1@@YAXP6AXQAH@Z1@Z"
+// X64: "?foo_fnptrbackref1@@YAXP6AXQEAH@Z1@Z"
+
+void foo_fnptrbackref2(ArrayFunPtr f1, ConstFunPtr f2) { }
+// CHECK: "?foo_fnptrbackref2@@YAXP6AXQAH@Z1@Z"
+// X64: "?foo_fnptrbackref2@@YAXP6AXQEAH@Z1@Z"
+
+typedef void (*NormalFunPtr)(int *d);
+void foo_fnptrbackref3(ArrayFunPtr f1, NormalFunPtr f2) { }
+// CHECK: "?foo_fnptrbackref3@@YAXP6AXQAH@Z1@Z"
+// X64: "?foo_fnptrbackref3@@YAXP6AXQEAH@Z1@Z"
+
+void foo_fnptrbackref4(NormalFunPtr f1, ArrayFunPtr f2) { }
+// CHECK: "?foo_fnptrbackref4@@YAXP6AXPAH@Z1@Z"
+// X64: "?foo_fnptrbackref4@@YAXP6AXPEAH@Z1@Z"
+
+ArrayFunPtr ret_fnptrarray() { return 0; }
+// CHECK: "?ret_fnptrarray@@YAP6AXQAH@ZXZ"
+// X64: "?ret_fnptrarray@@YAP6AXQEAH@ZXZ"
+
+// Test that we mangle the forward decl when we have a redeclaration with a
+// slightly different type.
+void mangle_fwd(char * const x);
+void mangle_fwd(char * x) {}
+// CHECK: "?mangle_fwd@@YAXQAD@Z"
+// X64: "?mangle_fwd@@YAXQEAD@Z"
+
+void mangle_no_fwd(char * x) {}
+// CHECK: "?mangle_no_fwd@@YAXPAD@Z"
+// X64: "?mangle_no_fwd@@YAXPEAD@Z"
+
+// The first argument gets mangled as-if it were written "int *const"
+// The second arg should not form a backref because it isn't qualified
+void mangle_no_backref0(int[], int *) {}
+// CHECK: "?mangle_no_backref0@@YAXQAHPAH@Z"
+// X64: "?mangle_no_backref0@@YAXQEAHPEAH@Z"
+
+void mangle_no_backref1(int[], int *const) {}
+// CHECK: "?mangle_no_backref1@@YAXQAHQAH@Z"
+// X64: "?mangle_no_backref1@@YAXQEAHQEAH@Z"
+
+typedef void fun_type(void);
+typedef void (*ptr_to_fun_type)(void);
+
+// Pointer to function types don't backref with function types
+void mangle_no_backref2(fun_type, ptr_to_fun_type) {}
+// CHECK: "?mangle_no_backref2@@YAXP6AXXZP6AXXZ@Z"
+// X64: "?mangle_no_backref2@@YAXP6AXXZP6AXXZ@Z"
+
+void mangle_yes_backref0(int[], int []) {}
+// CHECK: "?mangle_yes_backref0@@YAXQAH0@Z"
+// X64: "?mangle_yes_backref0@@YAXQEAH0@Z"
+
+void mangle_yes_backref1(int *const, int *const) {}
+// CHECK: "?mangle_yes_backref1@@YAXQAH0@Z"
+// X64: "?mangle_yes_backref1@@YAXQEAH0@Z"
+
+void mangle_yes_backref2(fun_type *const[], ptr_to_fun_type const[]) {}
+// CHECK: "?mangle_yes_backref2@@YAXQBQ6AXXZ0@Z"
+// X64: "?mangle_yes_backref2@@YAXQEBQ6AXXZ0@Z"
+
+void mangle_yes_backref3(ptr_to_fun_type *const, void (**const)(void)) {}
+// CHECK: "?mangle_yes_backref3@@YAXQAP6AXXZ0@Z"
+// X64: "?mangle_yes_backref3@@YAXQEAP6AXXZ0@Z"
+
+void mangle_yes_backref4(int *const __restrict, int *const __restrict) {}
+// CHECK: "?mangle_yes_backref4@@YAXQIAH0@Z"
+// X64: "?mangle_yes_backref4@@YAXQEIAH0@Z"
+
+struct S {};
+void pr23325(const S[1], const S[]) {}
+// CHECK: "?pr23325@@YAXQBUS@@0@Z"
+// X64: "?pr23325@@YAXQEBUS@@0@Z"
+
+void vla_arg(int i, int a[][i]) {}
+// CHECK: "?vla_arg@@YAXHQAY0A@H@Z"
+// X64: "?vla_arg@@YAXHQEAY0A@H@Z"
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-back-references-pr13207.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-back-references-pr13207.cpp
new file mode 100644
index 0000000..c68b97e
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-back-references-pr13207.cpp
@@ -0,0 +1,193 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
+
+template<class X, class Y, class Z>
+class A {};
+template<class X>
+class B {};
+template<class X>
+class C {};
+
+void foo_abbb(A<B<char>, B<char>, B<char> >) {}
+// CHECK: "?foo_abbb@@YAXV?$A@V?$B@D@@V1@V1@@@@Z"
+void foo_abb(A<char, B<char>, B<char> >) {}
+// CHECK: "?foo_abb@@YAXV?$A@DV?$B@D@@V1@@@@Z"
+void foo_abc(A<char, B<char>, C<char> >) {}
+// CHECK: "?foo_abc@@YAXV?$A@DV?$B@D@@V?$C@D@@@@@Z"
+void foo_bt(bool a, B<bool(bool)> b) {}
+// CHECK: "?foo_bt@@YAX_NV?$B@$$A6A_N_N@Z@@@Z"
+
+namespace N {
+template<class X, class Y, class Z>
+class A {};
+template<class X>
+class B {};
+template<class X>
+class C {};
+template<class X, class Y>
+class D {};
+class Z {};
+}
+
+void foo_abbb(N::A<N::B<char>, N::B<char>, N::B<char> >) {}
+// CHECK: "?foo_abbb@@YAXV?$A@V?$B@D@N@@V12@V12@@N@@@Z"
+void foo_abb(N::A<char, N::B<char>, N::B<char> >) {}
+// CHECK: "?foo_abb@@YAXV?$A@DV?$B@D@N@@V12@@N@@@Z"
+void foo_abc(N::A<char, N::B<char>, N::C<char> >) {}
+// CHECK: "?foo_abc@@YAXV?$A@DV?$B@D@N@@V?$C@D@2@@N@@@Z"
+
+N::A<char, N::B<char>, N::C<char> > abc_foo() {
+// CHECK: ?abc_foo@@YA?AV?$A@DV?$B@D@N@@V?$C@D@2@@N@@XZ
+ return N::A<char, N::B<char>, N::C<char> >();
+}
+
+N::Z z_foo(N::Z arg) {
+// CHECK: ?z_foo@@YA?AVZ@N@@V12@@Z
+ return arg;
+}
+
+N::B<char> b_foo(N::B<char> arg) {
+// CHECK: ?b_foo@@YA?AV?$B@D@N@@V12@@Z
+ return arg;
+}
+
+N::D<char, char> d_foo(N::D<char, char> arg) {
+// CHECK: ?d_foo@@YA?AV?$D@DD@N@@V12@@Z
+ return arg;
+}
+
+N::A<char, N::B<char>, N::C<char> > abc_foo_abc(N::A<char, N::B<char>, N::C<char> >) {
+// CHECK: ?abc_foo_abc@@YA?AV?$A@DV?$B@D@N@@V?$C@D@2@@N@@V12@@Z
+ return N::A<char, N::B<char>, N::C<char> >();
+}
+
+namespace NA {
+class X {};
+template<class T> class Y {};
+}
+
+namespace NB {
+class X {};
+template<class T> class Y {};
+}
+
+void foo5(NA::Y<NB::Y<NA::Y<NB::Y<NA::X> > > > arg) {}
+// CHECK: "?foo5@@YAXV?$Y@V?$Y@V?$Y@V?$Y@VX@NA@@@NB@@@NA@@@NB@@@NA@@@Z"
+
+void foo11(NA::Y<NA::X>, NB::Y<NA::X>) {}
+// CHECK: "?foo11@@YAXV?$Y@VX@NA@@@NA@@V1NB@@@Z"
+
+void foo112(NA::Y<NA::X>, NB::Y<NB::X>) {}
+// CHECK: "?foo112@@YAXV?$Y@VX@NA@@@NA@@V?$Y@VX@NB@@@NB@@@Z"
+
+void foo22(NA::Y<NB::Y<NA::X> >, NB::Y<NA::Y<NA::X> >) {}
+// CHECK: "?foo22@@YAXV?$Y@V?$Y@VX@NA@@@NB@@@NA@@V?$Y@V?$Y@VX@NA@@@NA@@@NB@@@Z"
+
+namespace PR13207 {
+class A {};
+class B {};
+class C {};
+
+template<class X>
+class F {};
+template<class X>
+class I {};
+template<class X, class Y>
+class J {};
+template<class X, class Y, class Z>
+class K {};
+
+class L {
+ public:
+ void foo(I<A> x) {}
+};
+// CHECK: "?foo@L@PR13207@@QAEXV?$I@VA@PR13207@@@2@@Z"
+
+void call_l_foo(L* l) { l->foo(I<A>()); }
+
+void foo(I<A> x) {}
+// CHECK: "?foo@PR13207@@YAXV?$I@VA@PR13207@@@1@@Z"
+void foo2(I<A> x, I<A> y) { }
+// CHECK: "?foo2@PR13207@@YAXV?$I@VA@PR13207@@@1@0@Z"
+void bar(J<A,B> x) {}
+// CHECK: "?bar@PR13207@@YAXV?$J@VA@PR13207@@VB@2@@1@@Z"
+void spam(K<A,B,C> x) {}
+// CHECK: "?spam@PR13207@@YAXV?$K@VA@PR13207@@VB@2@VC@2@@1@@Z"
+
+void baz(K<char, F<char>, I<char> >) {}
+// CHECK: "?baz@PR13207@@YAXV?$K@DV?$F@D@PR13207@@V?$I@D@2@@1@@Z"
+void qux(K<char, I<char>, I<char> >) {}
+// CHECK: "?qux@PR13207@@YAXV?$K@DV?$I@D@PR13207@@V12@@1@@Z"
+
+namespace NA {
+class X {};
+template<class T> class Y {};
+void foo(Y<X> x) {}
+// CHECK: "?foo@NA@PR13207@@YAXV?$Y@VX@NA@PR13207@@@12@@Z"
+void foofoo(Y<Y<X> > x) {}
+// CHECK: "?foofoo@NA@PR13207@@YAXV?$Y@V?$Y@VX@NA@PR13207@@@NA@PR13207@@@12@@Z"
+}
+
+namespace NB {
+class X {};
+template<class T> class Y {};
+void foo(Y<NA::X> x) {}
+// CHECK: "?foo@NB@PR13207@@YAXV?$Y@VX@NA@PR13207@@@12@@Z"
+
+void bar(NA::Y<X> x) {}
+// CHECK: "?bar@NB@PR13207@@YAXV?$Y@VX@NB@PR13207@@@NA@2@@Z"
+
+void spam(NA::Y<NA::X> x) {}
+// CHECK: "?spam@NB@PR13207@@YAXV?$Y@VX@NA@PR13207@@@NA@2@@Z"
+
+void foobar(NA::Y<Y<X> > a, Y<Y<X> >) {}
+// CHECK: "?foobar@NB@PR13207@@YAXV?$Y@V?$Y@VX@NB@PR13207@@@NB@PR13207@@@NA@2@V312@@Z"
+
+void foobarspam(Y<X> a, NA::Y<Y<X> > b, Y<Y<X> >) {}
+// CHECK: "?foobarspam@NB@PR13207@@YAXV?$Y@VX@NB@PR13207@@@12@V?$Y@V?$Y@VX@NB@PR13207@@@NB@PR13207@@@NA@2@V412@@Z"
+
+void foobarbaz(Y<X> a, NA::Y<Y<X> > b, Y<Y<X> >, Y<Y<X> > c) {}
+// CHECK: "?foobarbaz@NB@PR13207@@YAXV?$Y@VX@NB@PR13207@@@12@V?$Y@V?$Y@VX@NB@PR13207@@@NB@PR13207@@@NA@2@V412@2@Z"
+
+void foobarbazqux(Y<X> a, NA::Y<Y<X> > b, Y<Y<X> >, Y<Y<X> > c , NA::Y<Y<Y<X> > > d) {}
+// CHECK: "?foobarbazqux@NB@PR13207@@YAXV?$Y@VX@NB@PR13207@@@12@V?$Y@V?$Y@VX@NB@PR13207@@@NB@PR13207@@@NA@2@V412@2V?$Y@V?$Y@V?$Y@VX@NB@PR13207@@@NB@PR13207@@@NB@PR13207@@@52@@Z"
+}
+
+namespace NC {
+class X {};
+template<class T> class Y {};
+
+void foo(Y<NB::X> x) {}
+// CHECK: "?foo@NC@PR13207@@YAXV?$Y@VX@NB@PR13207@@@12@@Z"
+
+void foobar(NC::Y<NB::Y<NA::Y<NA::X> > > x) {}
+// CHECK: "?foobar@NC@PR13207@@YAXV?$Y@V?$Y@V?$Y@VX@NA@PR13207@@@NA@PR13207@@@NB@PR13207@@@12@@Z"
+}
+}
+
+// Function template names are not considered for backreferencing, but normal
+// function names are.
+namespace fn_space {
+struct RetVal { int hash; };
+template <typename T>
+RetVal fun_tmpl(const T &t) { return RetVal(); }
+RetVal fun_normal(int t) { return RetVal(); }
+void fun_instantiate() {
+ fun_normal(1);
+ fun_tmpl(1);
+}
+// CHECK: "?fun_normal@fn_space@@YA?AURetVal@1@H@Z"
+// CHECK: "??$fun_tmpl@H@fn_space@@YA?AURetVal@0@ABH@Z"
+
+template <typename T, RetVal (*F)(T)>
+RetVal fun_tmpl_recurse(T t) {
+ if (!t)
+ return RetVal();
+ return F(t - 1);
+}
+RetVal ident(int x) { return RetVal(); }
+void fun_instantiate2() {
+ fun_tmpl_recurse<int, fun_tmpl_recurse<int, ident> >(10);
+}
+// CHECK: "??$fun_tmpl_recurse@H$1??$fun_tmpl_recurse@H$1?ident@fn_space@@YA?AURetVal@2@H@Z@fn_space@@YA?AURetVal@1@H@Z@fn_space@@YA?AURetVal@0@H@Z"
+// CHECK: "??$fun_tmpl_recurse@H$1?ident@fn_space@@YA?AURetVal@2@H@Z@fn_space@@YA?AURetVal@0@H@Z"
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-back-references.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-back-references.cpp
new file mode 100644
index 0000000..cd4d1e2
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-back-references.cpp
@@ -0,0 +1,68 @@
+// RUN: %clang_cc1 -fms-extensions -fblocks -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
+
+void f1(const char* a, const char* b) {}
+// CHECK: "?f1@@YAXPBD0@Z"
+
+void f2(const char* a, char* b) {}
+// CHECK: "?f2@@YAXPBDPAD@Z"
+
+void f3(int a, const char* b, const char* c) {}
+// CHECK: "?f3@@YAXHPBD0@Z"
+
+const char *f4(const char* a, const char* b) { return 0; }
+// CHECK: "?f4@@YAPBDPBD0@Z"
+
+void f5(char const* a, unsigned int b, char c, void const* d, char const* e, unsigned int f) {}
+// CHECK: "?f5@@YAXPBDIDPBX0I@Z"
+
+void f6(bool a, bool b) {}
+// CHECK: "?f6@@YAX_N0@Z"
+
+void f7(int a, int* b, int c, int* d, bool e, bool f, bool* g) {}
+// CHECK: "?f7@@YAXHPAHH0_N1PA_N@Z"
+
+// FIXME: tests for more than 10 types?
+
+struct S {
+ void mbb(bool a, bool b) {}
+};
+
+void g1(struct S a) {}
+// CHECK: "?g1@@YAXUS@@@Z"
+
+void g2(struct S a, struct S b) {}
+// CHECK: "?g2@@YAXUS@@0@Z"
+
+void g3(struct S a, struct S b, struct S* c, struct S* d) {}
+// CHECK: "?g3@@YAXUS@@0PAU1@1@Z"
+
+void g4(const char* a, struct S* b, const char* c, struct S* d) {
+// CHECK: "?g4@@YAXPBDPAUS@@01@Z"
+ b->mbb(false, false);
+// CHECK: "?mbb@S@@QAEX_N0@Z"
+}
+
+// Make sure that different aliases of built-in types end up mangled as the
+// built-ins.
+typedef unsigned int uintptr_t;
+typedef unsigned int size_t;
+void *h(size_t a, uintptr_t b) { return 0; }
+// CHECK: "?h@@YAPAXII@Z"
+
+// Function pointers might be mangled in a complex way.
+typedef void (*VoidFunc)();
+typedef int* (*PInt3Func)(int* a, int* b);
+
+void h1(const char* a, const char* b, VoidFunc c, VoidFunc d) {}
+// CHECK: "?h1@@YAXPBD0P6AXXZ1@Z"
+
+void h2(void (*f_ptr)(void *), void *arg) {}
+// CHECK: "?h2@@YAXP6AXPAX@Z0@Z"
+
+PInt3Func h3(PInt3Func x, PInt3Func y, int* z) { return 0; }
+// CHECK: "?h3@@YAP6APAHPAH0@ZP6APAH00@Z10@Z"
+
+namespace foo {
+void foo() { }
+// CHECK: "?foo@0@YAXXZ"
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-cxx11.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-cxx11.cpp
new file mode 100644
index 0000000..1e3b7ce
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-cxx11.cpp
@@ -0,0 +1,360 @@
+// RUN: %clang_cc1 -std=c++11 -fms-extensions -emit-llvm %s -o - -triple=i386-pc-win32 -fms-compatibility-version=19.00 | FileCheck %s --check-prefix=CHECK --check-prefix=MSVC2015
+// RUN: %clang_cc1 -std=c++11 -fms-extensions -emit-llvm %s -o - -triple=i386-pc-win32 -fms-compatibility-version=18.00 | FileCheck %s --check-prefix=CHECK --check-prefix=MSVC2013
+// RUN: %clang_cc1 -std=c++11 -fms-extensions -emit-llvm %s -o - -triple=i386-pc-win32 -gcodeview -debug-info-kind=limited | FileCheck %s --check-prefix=DBG
+
+namespace FTypeWithQuals {
+template <typename T>
+struct S {};
+
+using A = int () const;
+S<A> a;
+// CHECK-DAG: @"?a@FTypeWithQuals@@3U?$S@$$A8@@BAHXZ@1@A"
+
+using B = int () volatile;
+S<B> b;
+// CHECK-DAG: @"?b@FTypeWithQuals@@3U?$S@$$A8@@CAHXZ@1@A"
+
+using C = int () __restrict;
+S<C> c;
+// CHECK-DAG: @"?c@FTypeWithQuals@@3U?$S@$$A8@@IAAHXZ@1@A"
+
+using D = int () const &;
+S<D> d;
+// CHECK-DAG: @"?d@FTypeWithQuals@@3U?$S@$$A8@@GBAHXZ@1@A"
+
+using E = int () volatile &;
+S<E> e;
+// CHECK-DAG: @"?e@FTypeWithQuals@@3U?$S@$$A8@@GCAHXZ@1@A"
+
+using F = int () __restrict &;
+S<F> f;
+// CHECK-DAG: @"?f@FTypeWithQuals@@3U?$S@$$A8@@IGAAHXZ@1@A"
+
+using G = int () const &&;
+S<G> g;
+// CHECK-DAG: @"?g@FTypeWithQuals@@3U?$S@$$A8@@HBAHXZ@1@A"
+
+using H = int () volatile &&;
+S<H> h;
+// CHECK-DAG: @"?h@FTypeWithQuals@@3U?$S@$$A8@@HCAHXZ@1@A"
+
+using I = int () __restrict &&;
+S<I> i;
+// CHECK-DAG: @"?i@FTypeWithQuals@@3U?$S@$$A8@@IHAAHXZ@1@A"
+
+using J = int ();
+S<J> j;
+// CHECK-DAG: @"?j@FTypeWithQuals@@3U?$S@$$A6AHXZ@1@A"
+
+using K = int () &;
+S<K> k;
+// CHECK-DAG: @"?k@FTypeWithQuals@@3U?$S@$$A8@@GAAHXZ@1@A"
+
+using L = int () &&;
+S<L> l;
+// CHECK-DAG: @"?l@FTypeWithQuals@@3U?$S@$$A8@@HAAHXZ@1@A"
+}
+
+// CHECK: "?DeducedType@@3HA"
+auto DeducedType = 30;
+
+// CHECK-DAG: @"?Char16Var@@3_SA"
+char16_t Char16Var;
+
+// CHECK-DAG: @"?Char32Var@@3_UA"
+char32_t Char32Var;
+
+// CHECK: "?LRef@@YAXAAH@Z"
+void LRef(int& a) { }
+
+// CHECK: "?RRef@@YAH$$QAH@Z"
+int RRef(int&& a) { return a; }
+
+// CHECK: "?Null@@YAX$$T@Z"
+namespace std { typedef decltype(__nullptr) nullptr_t; }
+void Null(std::nullptr_t) {}
+
+namespace EnumMangling {
+ extern enum Enum01 { } Enum;
+ extern enum Enum02 : bool { } BoolEnum;
+ extern enum Enum03 : char { } CharEnum;
+ extern enum Enum04 : signed char { } SCharEnum;
+ extern enum Enum05 : unsigned char { } UCharEnum;
+ extern enum Enum06 : short { } SShortEnum;
+ extern enum Enum07 : unsigned short { } UShortEnum;
+ extern enum Enum08 : int { } SIntEnum;
+ extern enum Enum09 : unsigned int { } UIntEnum;
+ extern enum Enum10 : long { } SLongEnum;
+ extern enum Enum11 : unsigned long { } ULongEnum;
+ extern enum Enum12 : long long { } SLongLongEnum;
+ extern enum Enum13 : unsigned long long { } ULongLongEnum;
+// CHECK-DAG: @"?Enum@EnumMangling@@3W4Enum01@1@A"
+// CHECK-DAG: @"?BoolEnum@EnumMangling@@3W4Enum02@1@A
+// CHECK-DAG: @"?CharEnum@EnumMangling@@3W4Enum03@1@A
+// CHECK-DAG: @"?SCharEnum@EnumMangling@@3W4Enum04@1@A
+// CHECK-DAG: @"?UCharEnum@EnumMangling@@3W4Enum05@1@A
+// CHECK-DAG: @"?SShortEnum@EnumMangling@@3W4Enum06@1@A"
+// CHECK-DAG: @"?UShortEnum@EnumMangling@@3W4Enum07@1@A"
+// CHECK-DAG: @"?SIntEnum@EnumMangling@@3W4Enum08@1@A"
+// CHECK-DAG: @"?UIntEnum@EnumMangling@@3W4Enum09@1@A"
+// CHECK-DAG: @"?SLongEnum@EnumMangling@@3W4Enum10@1@A"
+// CHECK-DAG: @"?ULongEnum@EnumMangling@@3W4Enum11@1@A"
+// CHECK-DAG: @"?SLongLongEnum@EnumMangling@@3W4Enum12@1@A"
+// CHECK-DAG: @"?ULongLongEnum@EnumMangling@@3W4Enum13@1@A"
+ decltype(Enum) *UseEnum() { return &Enum; }
+ decltype(BoolEnum) *UseBoolEnum() { return &BoolEnum; }
+ decltype(CharEnum) *UseCharEnum() { return &CharEnum; }
+ decltype(SCharEnum) *UseSCharEnum() { return &SCharEnum; }
+ decltype(UCharEnum) *UseUCharEnum() { return &UCharEnum; }
+ decltype(SShortEnum) *UseSShortEnum() { return &SShortEnum; }
+ decltype(UShortEnum) *UseUShortEnum() { return &UShortEnum; }
+ decltype(SIntEnum) *UseSIntEnum() { return &SIntEnum; }
+ decltype(UIntEnum) *UseUIntEnum() { return &UIntEnum; }
+ decltype(SLongEnum) *UseSLongEnum() { return &SLongEnum; }
+ decltype(ULongEnum) *UseULongEnum() { return &ULongEnum; }
+ decltype(SLongLongEnum) *UseSLongLongEnum() { return &SLongLongEnum; }
+ decltype(ULongLongEnum) *UseULongLongEnum() { return &ULongLongEnum; }
+ extern enum class EnumClass01 { } EnumClass;
+ extern enum class EnumClass02 : bool { } BoolEnumClass;
+ extern enum class EnumClass03 : char { } CharEnumClass;
+ extern enum class EnumClass04 : signed char { } SCharEnumClass;
+ extern enum class EnumClass05 : unsigned char { } UCharEnumClass;
+ extern enum class EnumClass06 : short { } SShortEnumClass;
+ extern enum class EnumClass07 : unsigned short { } UShortEnumClass;
+ extern enum class EnumClass08 : int { } SIntEnumClass;
+ extern enum class EnumClass09 : unsigned int { } UIntEnumClass;
+ extern enum class EnumClass10 : long { } SLongEnumClass;
+ extern enum class EnumClass11 : unsigned long { } ULongEnumClass;
+ extern enum class EnumClass12 : long long { } SLongLongEnumClass;
+ extern enum class EnumClass13 : unsigned long long { } ULongLongEnumClass;
+// CHECK-DAG: @"?EnumClass@EnumMangling@@3W4EnumClass01@1@A"
+// CHECK-DAG: @"?BoolEnumClass@EnumMangling@@3W4EnumClass02@1@A
+// CHECK-DAG: @"?CharEnumClass@EnumMangling@@3W4EnumClass03@1@A
+// CHECK-DAG: @"?SCharEnumClass@EnumMangling@@3W4EnumClass04@1@A
+// CHECK-DAG: @"?UCharEnumClass@EnumMangling@@3W4EnumClass05@1@A
+// CHECK-DAG: @"?SShortEnumClass@EnumMangling@@3W4EnumClass06@1@A"
+// CHECK-DAG: @"?UShortEnumClass@EnumMangling@@3W4EnumClass07@1@A"
+// CHECK-DAG: @"?SIntEnumClass@EnumMangling@@3W4EnumClass08@1@A"
+// CHECK-DAG: @"?UIntEnumClass@EnumMangling@@3W4EnumClass09@1@A"
+// CHECK-DAG: @"?SLongEnumClass@EnumMangling@@3W4EnumClass10@1@A"
+// CHECK-DAG: @"?ULongEnumClass@EnumMangling@@3W4EnumClass11@1@A"
+// CHECK-DAG: @"?SLongLongEnumClass@EnumMangling@@3W4EnumClass12@1@A"
+// CHECK-DAG: @"?ULongLongEnumClass@EnumMangling@@3W4EnumClass13@1@A"
+ decltype(EnumClass) *UseEnumClass() { return &EnumClass; }
+ decltype(BoolEnumClass) *UseBoolEnumClass() { return &BoolEnumClass; }
+ decltype(CharEnumClass) *UseCharEnumClass() { return &CharEnumClass; }
+ decltype(SCharEnumClass) *UseSCharEnumClass() { return &SCharEnumClass; }
+ decltype(UCharEnumClass) *UseUCharEnumClass() { return &UCharEnumClass; }
+ decltype(SShortEnumClass) *UseSShortEnumClass() { return &SShortEnumClass; }
+ decltype(UShortEnumClass) *UseUShortEnumClass() { return &UShortEnumClass; }
+ decltype(SIntEnumClass) *UseSIntEnumClass() { return &SIntEnumClass; }
+ decltype(UIntEnumClass) *UseUIntEnumClass() { return &UIntEnumClass; }
+ decltype(SLongEnumClass) *UseSLongEnumClass() { return &SLongEnumClass; }
+ decltype(ULongEnumClass) *UseULongEnumClass() { return &ULongEnumClass; }
+ decltype(SLongLongEnumClass) *UseSLongLongEnumClass() { return &SLongLongEnumClass; }
+ decltype(ULongLongEnumClass) *UseULongLongEnumClass() { return &ULongLongEnumClass; }
+}
+
+namespace PR18022 {
+
+struct { } a;
+decltype(a) fun(decltype(a) x, decltype(a)) { return x; }
+// CHECK-DAG: @"?fun@PR18022@@YA?AU<unnamed-type-a>@1@U21@0@Z"
+
+void use_fun() { fun(a, a); }
+
+}
+
+inline int define_lambda() {
+ static auto lambda = [] { static int local; ++local; return local; };
+// First, we have the static local variable of type "<lambda_1>" inside of
+// "define_lambda".
+// CHECK-DAG: @"?lambda@?1??define_lambda@@YAHXZ@4V<lambda_1>@?0??1@YAHXZ@A"
+// Next, we have the "operator()" for "<lambda_1>" which is inside of
+// "define_lambda".
+// CHECK-DAG: @"??R<lambda_1>@?0??define_lambda@@YAHXZ@QBE@XZ"
+// Finally, we have the local which is inside of "<lambda_1>" which is inside of
+// "define_lambda". Hooray.
+// MSVC2013-DAG: @"?local@?2???R<lambda_1>@?0??define_lambda@@YAHXZ@QBE@XZ@4HA"
+// MSVC2015-DAG: @"?local@?1???R<lambda_1>@?0??define_lambda@@YAHXZ@QBE@XZ@4HA"
+ return lambda();
+}
+
+template <typename T>
+void use_lambda_arg(T) {}
+
+inline void call_with_lambda_arg1() {
+ use_lambda_arg([]{});
+ // CHECK-DAG: @"??$use_lambda_arg@V<lambda_1>@?0??call_with_lambda_arg1@@YAXXZ@@@YAXV<lambda_1>@?0??call_with_lambda_arg1@@YAXXZ@@Z"
+}
+
+inline void call_with_lambda_arg2() {
+ use_lambda_arg([]{});
+ // CHECK-DAG: @"??$use_lambda_arg@V<lambda_1>@?0??call_with_lambda_arg2@@YAXXZ@@@YAXV<lambda_1>@?0??call_with_lambda_arg2@@YAXXZ@@Z"
+}
+
+int call_lambda() {
+ call_with_lambda_arg1();
+ call_with_lambda_arg2();
+ return define_lambda();
+}
+
+namespace PR19361 {
+struct A {
+ void foo() __restrict &;
+ void foo() __restrict &&;
+};
+void A::foo() __restrict & {}
+// CHECK-DAG: @"?foo@A@PR19361@@QIGAEXXZ"
+void A::foo() __restrict && {}
+// CHECK-DAG: @"?foo@A@PR19361@@QIHAEXXZ"
+}
+
+int operator"" _deg(long double) { return 0; }
+// CHECK-DAG: @"??__K_deg@@YAHO@Z"
+
+template <char...>
+void templ_fun_with_pack() {}
+
+template void templ_fun_with_pack<>();
+// CHECK-DAG: @"??$templ_fun_with_pack@$S@@YAXXZ"
+
+template <typename...>
+void templ_fun_with_ty_pack() {}
+
+template void templ_fun_with_ty_pack<>();
+// MSVC2013-DAG: @"??$templ_fun_with_ty_pack@$$$V@@YAXXZ"
+// MSVC2015-DAG: @"??$templ_fun_with_ty_pack@$$V@@YAXXZ"
+
+template <template <class> class...>
+void templ_fun_with_templ_templ_pack() {}
+
+template void templ_fun_with_templ_templ_pack<>();
+// MSVC2013-DAG: @"??$templ_fun_with_templ_templ_pack@$$$V@@YAXXZ"
+// MSVC2015-DAG: @"??$templ_fun_with_templ_templ_pack@$$V@@YAXXZ"
+
+namespace PR20047 {
+template <typename T>
+struct A {};
+
+template <typename T>
+using AliasA = A<T>;
+
+template <template <typename> class>
+void f() {}
+
+template void f<AliasA>();
+// CHECK-DAG: @"??$f@$$YAliasA@PR20047@@@PR20047@@YAXXZ"
+}
+
+namespace UnnamedType {
+struct A {
+ struct {} *TD;
+};
+
+void f(decltype(*A::TD)) {}
+// CHECK-DAG: @"?f@UnnamedType@@YAXAAU<unnamed-type-TD>@A@1@@Z"
+
+template <typename T>
+struct B {
+ enum {
+ } *e;
+};
+
+void f(decltype(B<int>::e)) {}
+// CHECK-DAG: @"?f@UnnamedType@@YAXPAW4<unnamed-type-e>@?$B@H@1@@Z
+}
+
+namespace PR24651 {
+template <typename T>
+void f(T) {}
+
+void g() {
+ enum {} E;
+ f(E);
+ {
+ enum {} E;
+ f(E);
+ }
+}
+// CHECK-DAG: @"??$f@W4<unnamed-type-E>@?1??g@PR24651@@YAXXZ@@PR24651@@YAXW4<unnamed-type-E>@?1??g@0@YAXXZ@@Z"
+// CHECK-DAG: @"??$f@W4<unnamed-type-E>@?2??g@PR24651@@YAXXZ@@PR24651@@YAXW4<unnamed-type-E>@?2??g@0@YAXXZ@@Z"
+}
+
+namespace PR18204 {
+template <typename T>
+int f(T *) { return 0; }
+static union {
+ int n = f(this);
+};
+// CHECK-DAG: @"??$f@T<unnamed-type-$S1>@PR18204@@@PR18204@@YAHPAT<unnamed-type-$S1>@0@@Z"
+}
+
+int PR26105() {
+ auto add = [](int x) { return ([x](int y) { return x + y; }); };
+ return add(3)(4);
+}
+// CHECK-DAG: @"??R<lambda_0>@?0??PR26105@@YAHXZ@QBE@H@Z"
+// CHECK-DAG: @"??R<lambda_1>@?0???R<lambda_0>@?0??PR26105@@YAHXZ@QBE@H@Z@QBE@H@Z"
+
+int __unaligned * unaligned_foo1() { return 0; }
+int __unaligned * __unaligned * unaligned_foo2() { return 0; }
+__unaligned int unaligned_foo3() { return 0; }
+void unaligned_foo4(int __unaligned *p1) {}
+void unaligned_foo5(int __unaligned * __restrict p1) {}
+template <typename T> T unaligned_foo6(T t) { return t; }
+void unaligned_foo7() { unaligned_foo6<int *>(0); unaligned_foo6<int __unaligned *>(0); }
+
+// CHECK-DAG: @"?unaligned_foo1@@YAPFAHXZ"
+// CHECK-DAG: @"?unaligned_foo2@@YAPFAPFAHXZ"
+// CHECK-DAG: @"?unaligned_foo3@@YAHXZ"
+// CHECK-DAG: @"?unaligned_foo4@@YAXPFAH@Z"
+// CHECK-DAG: @"?unaligned_foo5@@YAXPIFAH@Z"
+// CHECK-DAG: @"??$unaligned_foo6@PAH@@YAPAHPAH@Z"
+// CHECK-DAG: @"??$unaligned_foo6@PFAH@@YAPFAHPFAH@Z"
+
+// __unaligned qualifier for function types
+struct unaligned_foo8_S {
+ void unaligned_foo8() volatile __unaligned;
+};
+void unaligned_foo8_S::unaligned_foo8() volatile __unaligned {}
+
+// CHECK-DAG: @"?unaligned_foo8@unaligned_foo8_S@@QFCEXXZ"
+
+namespace PR31197 {
+struct A {
+ // CHECK-DAG: define linkonce_odr dso_local x86_thiscallcc i32* @"??R<lambda_1>@x@A@PR31197@@QBE@XZ"(
+ int *x = []() {
+ static int white;
+ // CHECK-DAG: @"?white@?1???R<lambda_1>@x@A@PR31197@@QBE@XZ@4HA"
+ return &white;
+ }();
+ // CHECK-DAG: define linkonce_odr dso_local x86_thiscallcc i32* @"??R<lambda_1>@y@A@PR31197@@QBE@XZ"(
+ int *y = []() {
+ static int black;
+ // CHECK-DAG: @"?black@?1???R<lambda_1>@y@A@PR31197@@QBE@XZ@4HA"
+ return &black;
+ }();
+ using FPtrTy = void(void);
+ static void default_args(FPtrTy x = [] {}, FPtrTy y = [] {}, int z = [] { return 1; }() + [] { return 2; }()) {}
+ // CHECK-DAG: @"??R<lambda_1_1>@?0??default_args@A@PR31197@@SAXP6AXXZ0H@Z@QBE@XZ"(
+ // CHECK-DAG: @"??R<lambda_1_2>@?0??default_args@A@PR31197@@SAXP6AXXZ0H@Z@QBE@XZ"(
+ // CHECK-DAG: @"??R<lambda_2_1>@?0??default_args@A@PR31197@@SAXP6AXXZ0H@Z@QBE@XZ"(
+ // CHECK-DAG: @"??R<lambda_3_1>@?0??default_args@A@PR31197@@SAXP6AXXZ0H@Z@QBE@XZ"(
+};
+A a;
+
+int call_it = (A::default_args(), 1);
+}
+
+enum { enumerator };
+void f(decltype(enumerator)) {}
+// CHECK-DAG: define internal void @"?f@@YAXW4<unnamed-enum-enumerator>@@@Z"(
+void use_f() { f(enumerator); }
+
+namespace pr37723 {
+struct s { enum {}; enum {}; };
+// DBG-DAG: DW_TAG_enumeration_type{{.*}}identifier: ".?AW4<unnamed-type-$S2>@s@pr37723@@"
+// DBG-DAG: DW_TAG_enumeration_type{{.*}}identifier: ".?AW4<unnamed-type-$S3>@s@pr37723@@"
+s x;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-cxx14.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-cxx14.cpp
new file mode 100644
index 0000000..c58d055
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-cxx14.cpp
@@ -0,0 +1,62 @@
+// RUN: %clang_cc1 -std=c++1y -fms-extensions -emit-llvm %s -o - -triple=i386-pc-win32 -fms-compatibility-version=19.00 | FileCheck -allow-deprecated-dag-overlap %s --check-prefix=CHECK --check-prefix=MSVC2015
+// RUN: %clang_cc1 -std=c++1y -fms-extensions -emit-llvm %s -o - -triple=i386-pc-win32 -fms-compatibility-version=18.00 | FileCheck -allow-deprecated-dag-overlap %s --check-prefix=CHECK --check-prefix=MSVC2013
+
+template <typename> int x = 0;
+
+// CHECK-DAG: "??$x@X@@3HA"
+template <> int x<void>;
+// CHECK-DAG: "??$x@H@@3HA"
+template <> int x<int>;
+
+// CHECK-DAG: "?FunctionWithLocalType@@YA?A?<auto>@@XZ"
+auto FunctionWithLocalType() {
+ struct LocalType {};
+ return LocalType{};
+}
+
+// CHECK-DAG: "?ValueFromFunctionWithLocalType@@3ULocalType@?1??FunctionWithLocalType@@YA?A?<auto>@@XZ@A"
+auto ValueFromFunctionWithLocalType = FunctionWithLocalType();
+
+// CHECK-DAG: "??R<lambda_0>@@QBE?A?<auto>@@XZ"
+auto LambdaWithLocalType = [] {
+ struct LocalType {};
+ return LocalType{};
+};
+
+// CHECK-DAG: "?ValueFromLambdaWithLocalType@@3ULocalType@?1???R<lambda_0>@@QBE?A?<auto>@@XZ@A"
+auto ValueFromLambdaWithLocalType = LambdaWithLocalType();
+
+template <typename T>
+auto TemplateFuncionWithLocalLambda(T) {
+ auto LocalLambdaWithLocalType = []() {
+ struct LocalType {};
+ return LocalType{};
+ };
+ return LocalLambdaWithLocalType();
+}
+
+// MSVC2013-DAG: "?ValueFromTemplateFuncionWithLocalLambda@@3ULocalType@?2???R<lambda_1>@?0???$TemplateFuncionWithLocalLambda@H@@YA?A?<auto>@@H@Z@QBE?A?3@XZ@A"
+// MSVC2013-DAG: "?ValueFromTemplateFuncionWithLocalLambda@@3ULocalType@?2???R<lambda_1>@?0???$TemplateFuncionWithLocalLambda@H@@YA?A?<auto>@@H@Z@QBE?A?3@XZ@A"
+// MSVC2015-DAG: "?ValueFromTemplateFuncionWithLocalLambda@@3ULocalType@?1???R<lambda_1>@?0???$TemplateFuncionWithLocalLambda@H@@YA?A?<auto>@@H@Z@QBE?A?3@XZ@A"
+// MSVC2015-DAG: "?ValueFromTemplateFuncionWithLocalLambda@@3ULocalType@?1???R<lambda_1>@?0???$TemplateFuncionWithLocalLambda@H@@YA?A?<auto>@@H@Z@QBE?A?3@XZ@A"
+// CHECK-DAG: "??$TemplateFuncionWithLocalLambda@H@@YA?A?<auto>@@H@Z"
+// CHECK-DAG: "??R<lambda_1>@?0???$TemplateFuncionWithLocalLambda@H@@YA?A?<auto>@@H@Z@QBE?A?1@XZ"
+auto ValueFromTemplateFuncionWithLocalLambda = TemplateFuncionWithLocalLambda(0);
+
+struct S;
+template <int S::*>
+int WithPMD = 0;
+
+template <> int WithPMD<nullptr>;
+// CHECK-DAG: "??$WithPMD@$GA@A@?0@@3HA"
+
+template <const int *, const int *>
+struct Foo {};
+
+Foo<&x<int>, &x<int>> Zoo;
+// CHECK-DAG: "?Zoo@@3U?$Foo@$1??$x@H@@3HA$1?1@3HA@@A"
+
+template <typename T> T unaligned_x;
+extern auto test_unaligned() { return unaligned_x<int __unaligned *>; }
+// CHECK-DAG: "??$unaligned_x@PFAH@@3PFAHA"
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-exception-spec.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-exception-spec.cpp
new file mode 100644
index 0000000..1aaf248
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-exception-spec.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -std=c++11 -fms-extensions -emit-llvm %s -o - -triple=x86_64-pc-win32 -Wno-noexcept-type -fms-compatibility-version=19.12 | FileCheck %s --check-prefix=CHECK --check-prefix=CXX11
+// RUN: %clang_cc1 -std=c++17 -fms-extensions -emit-llvm %s -o - -triple=x86_64-pc-win32 | FileCheck %s --check-prefix=CHECK --check-prefix=NOCOMPAT
+// RUN: %clang_cc1 -std=c++17 -fms-extensions -emit-llvm %s -o - -triple=x86_64-pc-win32 -fms-compatibility-version=19.12 | FileCheck %s --check-prefix=CHECK --check-prefix=CXX17
+
+// Prove that mangling only changed for noexcept types under /std:C++17, not all noexcept functions
+// CHECK-DAG: @"?nochange@@YAXXZ"
+void nochange() noexcept {}
+
+// CXX11-DAG: @"?a@@YAXP6AHXZ@Z"
+// NOCOMPAT-DAG: @"?a@@YAXP6AHXZ@Z"
+// CXX17-DAG: @"?a@@YAXP6AHX_E@Z"
+void a(int() noexcept) {}
+// CHECK-DAG: @"?b@@YAXP6AHXZ@Z"
+void b(int() noexcept(false)) {}
+// CXX11-DAG: @"?c@@YAXP6AHXZ@Z"
+// NOCOMPAT-DAG: @"?c@@YAXP6AHXZ@Z"
+// CXX17-DAG: @"?c@@YAXP6AHX_E@Z"
+void c(int() noexcept(true)) {}
+// CHECK-DAG: @"?d@@YAXP6AHXZ@Z"
+void d(int()) {}
+
+template <typename T>
+class e;
+template <typename T, typename... U>
+class e<T(U...) noexcept> {
+ // CXX11-DAG: @"?ee@?$e@$$A6AXXZ@@EEAAXXZ"
+ // NOCOMPAT-DAG: @"?ee@?$e@$$A6AXXZ@@EEAAXXZ"
+ // CXX17-DAG: @"?ee@?$e@$$A6AXX_E@@EEAAXXZ"
+ virtual T ee(U &&...) noexcept {};
+};
+
+e<void() noexcept> e1;
+
+template <typename T>
+class f;
+template <typename T, typename... U>
+class f<T(U...)> {
+ // CHECK-DAG: @"?ff@?$f@$$A6AXXZ@@EEAAXXZ"
+ virtual T ff(U &&...) noexcept {};
+};
+
+f<void()> f1;
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-md5.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-md5.cpp
new file mode 100644
index 0000000..740fd61
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-md5.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -emit-llvm -o - -triple i686-pc-win32 %s | FileCheck %s
+int xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
+// CHECK-DAG: @"??@bf7ea7b95f260b0b24e7f1e8fc8370ab@" = dso_local global i32 0, align 4
+
+struct yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy {
+ yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy();
+ virtual void f();
+};
+yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy::yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy() {}
+// CHECK-DAG: @"??@a6a285da2eea70dba6b578022be61d81@??_R4@" = linkonce_odr constant %rtti.CompleteObjectLocator
+// CHECK-DAG: @"??@a6a285da2eea70dba6b578022be61d81@" = unnamed_addr alias
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-return-qualifiers.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-return-qualifiers.cpp
new file mode 100644
index 0000000..0054279
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-return-qualifiers.cpp
@@ -0,0 +1,189 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
+
+void a1() {}
+// CHECK: "?a1@@YAXXZ"
+
+int a2() { return 0; }
+// CHECK: "?a2@@YAHXZ"
+
+const int a3() { return 0; }
+// CHECK: "?a3@@YA?BHXZ"
+
+volatile int a4() { return 0; }
+// CHECK: "?a4@@YA?CHXZ"
+
+const volatile int a5() { return 0; }
+// CHECK: "?a5@@YA?DHXZ"
+
+float a6() { return 0.0f; }
+// CHECK: "?a6@@YAMXZ"
+
+int *b1() { return 0; }
+// CHECK: "?b1@@YAPAHXZ"
+
+const char *b2() { return 0; }
+// CHECK: "?b2@@YAPBDXZ"
+
+float *b3() { return 0; }
+// CHECK: "?b3@@YAPAMXZ"
+
+const float *b4() { return 0; }
+// CHECK: "?b4@@YAPBMXZ"
+
+volatile float *b5() { return 0; }
+// CHECK: "?b5@@YAPCMXZ"
+
+const volatile float *b6() { return 0; }
+// CHECK: "?b6@@YAPDMXZ"
+
+float &b7() { return *(float*)0; }
+// CHECK: "?b7@@YAAAMXZ"
+
+const float &b8() { return *(float*)0; }
+// CHECK: "?b8@@YAABMXZ"
+
+volatile float &b9() { return *(float*)0; }
+// CHECK: "?b9@@YAACMXZ"
+
+const volatile float &b10() { return *(float*)0; }
+// CHECK: "?b10@@YAADMXZ"
+
+const char** b11() { return 0; }
+// CHECK: "?b11@@YAPAPBDXZ"
+
+class A {};
+
+A c1() { return A(); }
+// CHECK: "?c1@@YA?AVA@@XZ"
+
+const A c2() { return A(); }
+// CHECK: "?c2@@YA?BVA@@XZ"
+
+volatile A c3() { return A(); }
+// CHECK: "?c3@@YA?CVA@@XZ"
+
+const volatile A c4() { return A(); }
+// CHECK: "?c4@@YA?DVA@@XZ"
+
+const A* c5() { return 0; }
+// CHECK: "?c5@@YAPBVA@@XZ"
+
+volatile A* c6() { return 0; }
+// CHECK: "?c6@@YAPCVA@@XZ"
+
+const volatile A* c7() { return 0; }
+// CHECK: "?c7@@YAPDVA@@XZ"
+
+A &c8() { return *(A*)0; }
+// CHECK: "?c8@@YAAAVA@@XZ"
+
+const A &c9() { return *(A*)0; }
+// CHECK: "?c9@@YAABVA@@XZ"
+
+volatile A &c10() { return *(A*)0; }
+// CHECK: "?c10@@YAACVA@@XZ"
+
+const volatile A &c11() { return *(A*)0; }
+// CHECK: "?c11@@YAADVA@@XZ"
+
+template<typename T> class B {};
+
+B<int> d1() { return B<int>(); }
+// CHECK: "?d1@@YA?AV?$B@H@@XZ"
+
+B<const char*> d2() {return B<const char*>(); }
+// CHECK: "?d2@@YA?AV?$B@PBD@@XZ"
+
+B<A> d3() {return B<A>(); }
+// CHECK: "?d3@@YA?AV?$B@VA@@@@XZ"
+
+B<A>* d4() { return 0; }
+// CHECK: "?d4@@YAPAV?$B@VA@@@@XZ"
+
+const B<A>* d5() { return 0; }
+// CHECK: "?d5@@YAPBV?$B@VA@@@@XZ"
+
+volatile B<A>* d6() { return 0; }
+// CHECK: "?d6@@YAPCV?$B@VA@@@@XZ"
+
+const volatile B<A>* d7() { return 0; }
+// CHECK: "?d7@@YAPDV?$B@VA@@@@XZ"
+
+B<A>& d8() { return *(B<A>*)0; }
+// CHECK: "?d8@@YAAAV?$B@VA@@@@XZ"
+
+const B<A>& d9() { return *(B<A>*)0; }
+// CHECK: "?d9@@YAABV?$B@VA@@@@XZ"
+
+volatile B<A>& d10() { return *(B<A>*)0; }
+// CHECK: "?d10@@YAACV?$B@VA@@@@XZ"
+
+const volatile B<A>& d11() { return *(B<A>*)0; }
+// CHECK: "?d11@@YAADV?$B@VA@@@@XZ"
+
+enum Enum { DEFAULT };
+
+Enum e1() { return DEFAULT; }
+// CHECK: "?e1@@YA?AW4Enum@@XZ"
+
+const Enum e2() { return DEFAULT; }
+// CHECK: "?e2@@YA?BW4Enum@@XZ"
+
+Enum* e3() { return 0; }
+// CHECK: "?e3@@YAPAW4Enum@@XZ"
+
+Enum& e4() { return *(Enum*)0; }
+// CHECK: "?e4@@YAAAW4Enum@@XZ"
+
+struct S {};
+
+struct S f1() { struct S s; return s; }
+// CHECK: "?f1@@YA?AUS@@XZ"
+
+const struct S f2() { struct S s; return s; }
+// CHECK: "?f2@@YA?BUS@@XZ"
+
+struct S* f3() { return 0; }
+// CHECK: "?f3@@YAPAUS@@XZ"
+
+const struct S* f4() { return 0; }
+// CHECK: "?f4@@YAPBUS@@XZ"
+
+const volatile struct S* f5() { return 0; }
+// CHECK: "?f5@@YAPDUS@@XZ"
+
+struct S& f6() { return *(struct S*)0; }
+// CHECK: "?f6@@YAAAUS@@XZ"
+
+struct S* const f7() { return 0; }
+// CHECK: "?f7@@YAQAUS@@XZ"
+
+int S::* f8() { return 0; }
+// CHECK: "?f8@@YAPQS@@HXZ"
+
+int S::* const f9() { return 0; }
+// CHECK: "?f9@@YAQQS@@HXZ"
+
+int S::* __restrict f10() { return 0; }
+// CHECK: "?f10@@YAPIQS@@HXZ"
+
+int S::* const __restrict f11() { return 0; }
+// CHECK: "?f11@@YAQIQS@@HXZ"
+
+typedef int (*function_pointer)(int);
+
+function_pointer g1() { return 0; }
+// CHECK: "?g1@@YAP6AHH@ZXZ"
+
+const function_pointer g2() { return 0; }
+// CHECK: "?g2@@YAQ6AHH@ZXZ"
+
+function_pointer* g3() { return 0; }
+// CHECK: "?g3@@YAPAP6AHH@ZXZ"
+
+const function_pointer* g4() { return 0; }
+// CHECK: "?g4@@YAPBQ6AHH@ZXZ"
+
+extern int &z;
+int & __restrict h1() { return z; }
+// CHECK: "?h1@@YAAIAHXZ"
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-string-literals.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-string-literals.cpp
new file mode 100644
index 0000000..214586d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-string-literals.cpp
@@ -0,0 +1,753 @@
+// RUN: %clang_cc1 -x c++ -std=c++11 -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
+// RUN: %clang_cc1 -x c++ -std=c++11 -emit-llvm %s -o - -triple=x86_64-pc-win32 | FileCheck %s
+
+const char *l255 = "\xff";
+const char *l254 = "\xfe";
+const char *l253 = "\xfd";
+const char *l252 = "\xfc";
+const char *l251 = "\xfb";
+const char *l250 = "\xfa";
+const char *l249 = "\xf9";
+const char *l248 = "\xf8";
+const char *l247 = "\xf7";
+const char *l246 = "\xf6";
+const char *l245 = "\xf5";
+const char *l244 = "\xf4";
+const char *l243 = "\xf3";
+const char *l242 = "\xf2";
+const char *l241 = "\xf1";
+const char *l240 = "\xf0";
+const char *l239 = "\xef";
+const char *l238 = "\xee";
+const char *l237 = "\xed";
+const char *l236 = "\xec";
+const char *l235 = "\xeb";
+const char *l234 = "\xea";
+const char *l233 = "\xe9";
+const char *l232 = "\xe8";
+const char *l231 = "\xe7";
+const char *l230 = "\xe6";
+const char *l229 = "\xe5";
+const char *l228 = "\xe4";
+const char *l227 = "\xe3";
+const char *l226 = "\xe2";
+const char *l225 = "\xe1";
+const char *l224 = "\xe0";
+const char *l223 = "\xdf";
+const char *l222 = "\xde";
+const char *l221 = "\xdd";
+const char *l220 = "\xdc";
+const char *l219 = "\xdb";
+const char *l218 = "\xda";
+const char *l217 = "\xd9";
+const char *l216 = "\xd8";
+const char *l215 = "\xd7";
+const char *l214 = "\xd6";
+const char *l213 = "\xd5";
+const char *l212 = "\xd4";
+const char *l211 = "\xd3";
+const char *l210 = "\xd2";
+const char *l209 = "\xd1";
+const char *l208 = "\xd0";
+const char *l207 = "\xcf";
+const char *l206 = "\xce";
+const char *l205 = "\xcd";
+const char *l204 = "\xcc";
+const char *l203 = "\xcb";
+const char *l202 = "\xca";
+const char *l201 = "\xc9";
+const char *l200 = "\xc8";
+const char *l199 = "\xc7";
+const char *l198 = "\xc6";
+const char *l197 = "\xc5";
+const char *l196 = "\xc4";
+const char *l195 = "\xc3";
+const char *l194 = "\xc2";
+const char *l193 = "\xc1";
+const char *l192 = "\xc0";
+const char *l191 = "\xbf";
+const char *l190 = "\xbe";
+const char *l189 = "\xbd";
+const char *l188 = "\xbc";
+const char *l187 = "\xbb";
+const char *l186 = "\xba";
+const char *l185 = "\xb9";
+const char *l184 = "\xb8";
+const char *l183 = "\xb7";
+const char *l182 = "\xb6";
+const char *l181 = "\xb5";
+const char *l180 = "\xb4";
+const char *l179 = "\xb3";
+const char *l178 = "\xb2";
+const char *l177 = "\xb1";
+const char *l176 = "\xb0";
+const char *l175 = "\xaf";
+const char *l174 = "\xae";
+const char *l173 = "\xad";
+const char *l172 = "\xac";
+const char *l171 = "\xab";
+const char *l170 = "\xaa";
+const char *l169 = "\xa9";
+const char *l168 = "\xa8";
+const char *l167 = "\xa7";
+const char *l166 = "\xa6";
+const char *l165 = "\xa5";
+const char *l164 = "\xa4";
+const char *l163 = "\xa3";
+const char *l162 = "\xa2";
+const char *l161 = "\xa1";
+const char *l160 = "\xa0";
+const char *l159 = "\x9f";
+const char *l158 = "\x9e";
+const char *l157 = "\x9d";
+const char *l156 = "\x9c";
+const char *l155 = "\x9b";
+const char *l154 = "\x9a";
+const char *l153 = "\x99";
+const char *l152 = "\x98";
+const char *l151 = "\x97";
+const char *l150 = "\x96";
+const char *l149 = "\x95";
+const char *l148 = "\x94";
+const char *l147 = "\x93";
+const char *l146 = "\x92";
+const char *l145 = "\x91";
+const char *l144 = "\x90";
+const char *l143 = "\x8f";
+const char *l142 = "\x8e";
+const char *l141 = "\x8d";
+const char *l140 = "\x8c";
+const char *l139 = "\x8b";
+const char *l138 = "\x8a";
+const char *l137 = "\x89";
+const char *l136 = "\x88";
+const char *l135 = "\x87";
+const char *l134 = "\x86";
+const char *l133 = "\x85";
+const char *l132 = "\x84";
+const char *l131 = "\x83";
+const char *l130 = "\x82";
+const char *l129 = "\x81";
+const char *l128 = "\x80";
+const char *l127 = "\x7f";
+const char *l126 = "\x7e";
+const char *l125 = "\x7d";
+const char *l124 = "\x7c";
+const char *l123 = "\x7b";
+const char *l122 = "\x7a";
+const char *l121 = "\x79";
+const char *l120 = "\x78";
+const char *l119 = "\x77";
+const char *l118 = "\x76";
+const char *l117 = "\x75";
+const char *l116 = "\x74";
+const char *l115 = "\x73";
+const char *l114 = "\x72";
+const char *l113 = "\x71";
+const char *l112 = "\x70";
+const char *l111 = "\x6f";
+const char *l110 = "\x6e";
+const char *l109 = "\x6d";
+const char *l108 = "\x6c";
+const char *l107 = "\x6b";
+const char *l106 = "\x6a";
+const char *l105 = "\x69";
+const char *l104 = "\x68";
+const char *l103 = "\x67";
+const char *l102 = "\x66";
+const char *l101 = "\x65";
+const char *l100 = "\x64";
+const char *l99 = "\x63";
+const char *l98 = "\x62";
+const char *l97 = "\x61";
+const char *l96 = "\x60";
+const char *l95 = "\x5f";
+const char *l94 = "\x5e";
+const char *l93 = "\x5d";
+const char *l92 = "\x5c";
+const char *l91 = "\x5b";
+const char *l90 = "\x5a";
+const char *l89 = "\x59";
+const char *l88 = "\x58";
+const char *l87 = "\x57";
+const char *l86 = "\x56";
+const char *l85 = "\x55";
+const char *l84 = "\x54";
+const char *l83 = "\x53";
+const char *l82 = "\x52";
+const char *l81 = "\x51";
+const char *l80 = "\x50";
+const char *l79 = "\x4f";
+const char *l78 = "\x4e";
+const char *l77 = "\x4d";
+const char *l76 = "\x4c";
+const char *l75 = "\x4b";
+const char *l74 = "\x4a";
+const char *l73 = "\x49";
+const char *l72 = "\x48";
+const char *l71 = "\x47";
+const char *l70 = "\x46";
+const char *l69 = "\x45";
+const char *l68 = "\x44";
+const char *l67 = "\x43";
+const char *l66 = "\x42";
+const char *l65 = "\x41";
+const char *l64 = "\x40";
+const char *l63 = "\x3f";
+const char *l62 = "\x3e";
+const char *l61 = "\x3d";
+const char *l60 = "\x3c";
+const char *l59 = "\x3b";
+const char *l58 = "\x3a";
+const char *l57 = "\x39";
+const char *l56 = "\x38";
+const char *l55 = "\x37";
+const char *l54 = "\x36";
+const char *l53 = "\x35";
+const char *l52 = "\x34";
+const char *l51 = "\x33";
+const char *l50 = "\x32";
+const char *l49 = "\x31";
+const char *l48 = "\x30";
+const char *l47 = "\x2f";
+const char *l46 = "\x2e";
+const char *l45 = "\x2d";
+const char *l44 = "\x2c";
+const char *l43 = "\x2b";
+const char *l42 = "\x2a";
+const char *l41 = "\x29";
+const char *l40 = "\x28";
+const char *l39 = "\x27";
+const char *l38 = "\x26";
+const char *l37 = "\x25";
+const char *l36 = "\x24";
+const char *l35 = "\x23";
+const char *l34 = "\x22";
+const char *l33 = "\x21";
+const char *l32 = "\x20";
+const char *l31 = "\x1f";
+const char *l30 = "\x1e";
+const char *l29 = "\x1d";
+const char *l28 = "\x1c";
+const char *l27 = "\x1b";
+const char *l26 = "\x1a";
+const char *l25 = "\x19";
+const char *l24 = "\x18";
+const char *l23 = "\x17";
+const char *l22 = "\x16";
+const char *l21 = "\x15";
+const char *l20 = "\x14";
+const char *l19 = "\x13";
+const char *l18 = "\x12";
+const char *l17 = "\x11";
+const char *l16 = "\x10";
+const char *l15 = "\xf";
+const char *l14 = "\xe";
+const char *l13 = "\xd";
+const char *l12 = "\xc";
+const char *l11 = "\xb";
+const char *l10 = "\xa";
+const char *l9 = "\x9";
+const char *l8 = "\x8";
+const char *l7 = "\x7";
+const char *l6 = "\x6";
+const char *l5 = "\x5";
+const char *l4 = "\x4";
+const char *l3 = "\x3";
+const char *l2 = "\x2";
+const char *l1 = "\x1";
+const char *l0 = "\x0";
+
+// CHECK: @"??_C@_01CNACBAHC@?$PP?$AA@"
+// CHECK: @"??_C@_01DEBJCBDD@?$PO?$AA@"
+// CHECK: @"??_C@_01BPDEHCPA@?$PN?$AA@"
+// CHECK: @"??_C@_01GCPEDLB@?$PM?$AA@"
+// CHECK: @"??_C@_01EJGONFHG@?$PL?$AA@"
+// CHECK: @"??_C@_01FAHFOEDH@?z?$AA@"
+// CHECK: @"??_C@_01HLFILHPE@?y?$AA@"
+// CHECK: @"??_C@_01GCEDIGLF@?x?$AA@"
+// CHECK: @"??_C@_01OFNLJKHK@?w?$AA@"
+// CHECK: @"??_C@_01PMMAKLDL@?v?$AA@"
+// CHECK: @"??_C@_01NHONPIPI@?u?$AA@"
+// CHECK: @"??_C@_01MOPGMJLJ@?t?$AA@"
+// CHECK: @"??_C@_01IBLHFPHO@?s?$AA@"
+// CHECK: @"??_C@_01JIKMGODP@?r?$AA@"
+// CHECK: @"??_C@_01LDIBDNPM@?q?$AA@"
+// CHECK: @"??_C@_01KKJKAMLN@?p?$AA@"
+// CHECK: @"??_C@_01GHMAACCD@?o?$AA@"
+// CHECK: @"??_C@_01HONLDDGC@?n?$AA@"
+// CHECK: @"??_C@_01FFPGGAKB@?m?$AA@"
+// CHECK: @"??_C@_01EMONFBOA@?l?$AA@"
+// CHECK: @"??_C@_01DKMMHCH@?k?$AA@"
+// CHECK: @"??_C@_01BKLHPGGG@?j?$AA@"
+// CHECK: @"??_C@_01DBJKKFKF@?i?$AA@"
+// CHECK: @"??_C@_01CIIBJEOE@?h?$AA@"
+// CHECK: @"??_C@_01KPBJIICL@?g?$AA@"
+// CHECK: @"??_C@_01LGACLJGK@?f?$AA@"
+// CHECK: @"??_C@_01JNCPOKKJ@?e?$AA@"
+// CHECK: @"??_C@_01IEDENLOI@?d?$AA@"
+// CHECK: @"??_C@_01MLHFENCP@?c?$AA@"
+// CHECK: @"??_C@_01NCGOHMGO@?b?$AA@"
+// CHECK: @"??_C@_01PJEDCPKN@?a?$AA@"
+// CHECK: @"??_C@_01OAFIBOOM@?$OA?$AA@"
+// CHECK: @"??_C@_01LIIGDENA@?$NP?$AA@"
+// CHECK: @"??_C@_01KBJNAFJB@?$NO?$AA@"
+// CHECK: @"??_C@_01IKLAFGFC@?$NN?$AA@"
+// CHECK: @"??_C@_01JDKLGHBD@?$NM?$AA@"
+// CHECK: @"??_C@_01NMOKPBNE@?$NL?$AA@"
+// CHECK: @"??_C@_01MFPBMAJF@?Z?$AA@"
+// CHECK: @"??_C@_01OONMJDFG@?Y?$AA@"
+// CHECK: @"??_C@_01PHMHKCBH@?X?$AA@"
+// CHECK: @"??_C@_01HAFPLONI@?W?$AA@"
+// CHECK: @"??_C@_01GJEEIPJJ@?V?$AA@"
+// CHECK: @"??_C@_01ECGJNMFK@?U?$AA@"
+// CHECK: @"??_C@_01FLHCONBL@?T?$AA@"
+// CHECK: @"??_C@_01BEDDHLNM@?S?$AA@"
+// CHECK: @"??_C@_01NCIEKJN@?R?$AA@"
+// CHECK: @"??_C@_01CGAFBJFO@?Q?$AA@"
+// CHECK: @"??_C@_01DPBOCIBP@?P?$AA@"
+// CHECK: @"??_C@_01PCEECGIB@?O?$AA@"
+// CHECK: @"??_C@_01OLFPBHMA@?N?$AA@"
+// CHECK: @"??_C@_01MAHCEEAD@?M?$AA@"
+// CHECK: @"??_C@_01NJGJHFEC@?L?$AA@"
+// CHECK: @"??_C@_01JGCIODIF@?K?$AA@"
+// CHECK: @"??_C@_01IPDDNCME@?J?$AA@"
+// CHECK: @"??_C@_01KEBOIBAH@?I?$AA@"
+// CHECK: @"??_C@_01LNAFLAEG@?H?$AA@"
+// CHECK: @"??_C@_01DKJNKMIJ@?G?$AA@"
+// CHECK: @"??_C@_01CDIGJNMI@?F?$AA@"
+// CHECK: @"??_C@_01IKLMOAL@?E?$AA@"
+// CHECK: @"??_C@_01BBLAPPEK@?D?$AA@"
+// CHECK: @"??_C@_01FOPBGJIN@?C?$AA@"
+// CHECK: @"??_C@_01EHOKFIMM@?B?$AA@"
+// CHECK: @"??_C@_01GMMHALAP@?A?$AA@"
+// CHECK: @"??_C@_01HFNMDKEO@?$MA?$AA@"
+// CHECK: @"??_C@_01NNHLFPHH@?$LP?$AA@"
+// CHECK: @"??_C@_01MEGAGODG@?$LO?$AA@"
+// CHECK: @"??_C@_01OPENDNPF@?$LN?$AA@"
+// CHECK: @"??_C@_01PGFGAMLE@?$LM?$AA@"
+// CHECK: @"??_C@_01LJBHJKHD@?$LL?$AA@"
+// CHECK: @"??_C@_01KAAMKLDC@?$LK?$AA@"
+// CHECK: @"??_C@_01ILCBPIPB@?$LJ?$AA@"
+// CHECK: @"??_C@_01JCDKMJLA@?$LI?$AA@"
+// CHECK: @"??_C@_01BFKCNFHP@?$LH?$AA@"
+// CHECK: @"??_C@_01MLJOEDO@?$LG?$AA@"
+// CHECK: @"??_C@_01CHJELHPN@?$LF?$AA@"
+// CHECK: @"??_C@_01DOIPIGLM@?$LE?$AA@"
+// CHECK: @"??_C@_01HBMOBAHL@?$LD?$AA@"
+// CHECK: @"??_C@_01GINFCBDK@?$LC?$AA@"
+// CHECK: @"??_C@_01EDPIHCPJ@?$LB?$AA@"
+// CHECK: @"??_C@_01FKODEDLI@?$LA?$AA@"
+// CHECK: @"??_C@_01JHLJENCG@?$KP?$AA@"
+// CHECK: @"??_C@_01IOKCHMGH@?$KO?$AA@"
+// CHECK: @"??_C@_01KFIPCPKE@?$KN?$AA@"
+// CHECK: @"??_C@_01LMJEBOOF@?$KM?$AA@"
+// CHECK: @"??_C@_01PDNFIICC@?$KL?$AA@"
+// CHECK: @"??_C@_01OKMOLJGD@?$KK?$AA@"
+// CHECK: @"??_C@_01MBODOKKA@?$KJ?$AA@"
+// CHECK: @"??_C@_01NIPINLOB@?$KI?$AA@"
+// CHECK: @"??_C@_01FPGAMHCO@?$KH?$AA@"
+// CHECK: @"??_C@_01EGHLPGGP@?$KG?$AA@"
+// CHECK: @"??_C@_01GNFGKFKM@?$KF?$AA@"
+// CHECK: @"??_C@_01HEENJEON@?$KE?$AA@"
+// CHECK: @"??_C@_01DLAMACCK@?$KD?$AA@"
+// CHECK: @"??_C@_01CCBHDDGL@?$KC?$AA@"
+// CHECK: @"??_C@_01JDKGAKI@?$KB?$AA@"
+// CHECK: @"??_C@_01BACBFBOJ@?$KA?$AA@"
+// CHECK: @"??_C@_01EIPPHLNF@?$JP?$AA@"
+// CHECK: @"??_C@_01FBOEEKJE@?$JO?$AA@"
+// CHECK: @"??_C@_01HKMJBJFH@?$JN?$AA@"
+// CHECK: @"??_C@_01GDNCCIBG@?$JM?$AA@"
+// CHECK: @"??_C@_01CMJDLONB@?$JL?$AA@"
+// CHECK: @"??_C@_01DFIIIPJA@?$JK?$AA@"
+// CHECK: @"??_C@_01BOKFNMFD@?$JJ?$AA@"
+// CHECK: @"??_C@_01HLOONBC@?$JI?$AA@"
+// CHECK: @"??_C@_01IACGPBNN@?$JH?$AA@"
+// CHECK: @"??_C@_01JJDNMAJM@?$JG?$AA@"
+// CHECK: @"??_C@_01LCBAJDFP@?$JF?$AA@"
+// CHECK: @"??_C@_01KLALKCBO@?$JE?$AA@"
+// CHECK: @"??_C@_01OEEKDENJ@?$JD?$AA@"
+// CHECK: @"??_C@_01PNFBAFJI@?$JC?$AA@"
+// CHECK: @"??_C@_01NGHMFGFL@?$JB?$AA@"
+// CHECK: @"??_C@_01MPGHGHBK@?$JA?$AA@"
+// CHECK: @"??_C@_01CDNGJIE@?$IP?$AA@"
+// CHECK: @"??_C@_01BLCGFIMF@?$IO?$AA@"
+// CHECK: @"??_C@_01DAALALAG@?$IN?$AA@"
+// CHECK: @"??_C@_01CJBADKEH@?$IM?$AA@"
+// CHECK: @"??_C@_01GGFBKMIA@?$IL?$AA@"
+// CHECK: @"??_C@_01HPEKJNMB@?$IK?$AA@"
+// CHECK: @"??_C@_01FEGHMOAC@?$IJ?$AA@"
+// CHECK: @"??_C@_01ENHMPPED@?$II?$AA@"
+// CHECK: @"??_C@_01MKOEODIM@?$IH?$AA@"
+// CHECK: @"??_C@_01NDPPNCMN@?$IG?$AA@"
+// CHECK: @"??_C@_01PINCIBAO@?$IF?$AA@"
+// CHECK: @"??_C@_01OBMJLAEP@?$IE?$AA@"
+// CHECK: @"??_C@_01KOIICGII@?$ID?$AA@"
+// CHECK: @"??_C@_01LHJDBHMJ@?$IC?$AA@"
+// CHECK: @"??_C@_01JMLOEEAK@?$IB?$AA@"
+// CHECK: @"??_C@_01IFKFHFEL@?$IA?$AA@"
+// CHECK: @"??_C@_01BGIBIIDJ@?$HP?$AA@"
+// CHECK: @"??_C@_01PJKLJHI@?$HO?$AA@"
+// CHECK: @"??_C@_01CELHOKLL@?$HN?$AA@"
+// CHECK: @"??_C@_01DNKMNLPK@?$HM?$AA@"
+// CHECK: @"??_C@_01HCONENDN@?$HL?$AA@"
+// CHECK: @"??_C@_01GLPGHMHM@z?$AA@"
+// CHECK: @"??_C@_01EANLCPLP@y?$AA@"
+// CHECK: @"??_C@_01FJMABOPO@x?$AA@"
+// CHECK: @"??_C@_01NOFIACDB@w?$AA@"
+// CHECK: @"??_C@_01MHEDDDHA@v?$AA@"
+// CHECK: @"??_C@_01OMGOGALD@u?$AA@"
+// CHECK: @"??_C@_01PFHFFBPC@t?$AA@"
+// CHECK: @"??_C@_01LKDEMHDF@s?$AA@"
+// CHECK: @"??_C@_01KDCPPGHE@r?$AA@"
+// CHECK: @"??_C@_01IIACKFLH@q?$AA@"
+// CHECK: @"??_C@_01JBBJJEPG@p?$AA@"
+// CHECK: @"??_C@_01FMEDJKGI@o?$AA@"
+// CHECK: @"??_C@_01EFFIKLCJ@n?$AA@"
+// CHECK: @"??_C@_01GOHFPIOK@m?$AA@"
+// CHECK: @"??_C@_01HHGOMJKL@l?$AA@"
+// CHECK: @"??_C@_01DICPFPGM@k?$AA@"
+// CHECK: @"??_C@_01CBDEGOCN@j?$AA@"
+// CHECK: @"??_C@_01KBJDNOO@i?$AA@"
+// CHECK: @"??_C@_01BDACAMKP@h?$AA@"
+// CHECK: @"??_C@_01JEJKBAGA@g?$AA@"
+// CHECK: @"??_C@_01INIBCBCB@f?$AA@"
+// CHECK: @"??_C@_01KGKMHCOC@e?$AA@"
+// CHECK: @"??_C@_01LPLHEDKD@d?$AA@"
+// CHECK: @"??_C@_01PAPGNFGE@c?$AA@"
+// CHECK: @"??_C@_01OJONOECF@b?$AA@"
+// CHECK: @"??_C@_01MCMALHOG@a?$AA@"
+// CHECK: @"??_C@_01NLNLIGKH@?$GA?$AA@"
+// CHECK: @"??_C@_01IDAFKMJL@_?$AA@"
+// CHECK: @"??_C@_01JKBOJNNK@?$FO?$AA@"
+// CHECK: @"??_C@_01LBDDMOBJ@?$FN?$AA@"
+// CHECK: @"??_C@_01KICIPPFI@?2?$AA@"
+// CHECK: @"??_C@_01OHGJGJJP@?$FL?$AA@"
+// CHECK: @"??_C@_01POHCFINO@Z?$AA@"
+// CHECK: @"??_C@_01NFFPALBN@Y?$AA@"
+// CHECK: @"??_C@_01MMEEDKFM@X?$AA@"
+// CHECK: @"??_C@_01ELNMCGJD@W?$AA@"
+// CHECK: @"??_C@_01FCMHBHNC@V?$AA@"
+// CHECK: @"??_C@_01HJOKEEBB@U?$AA@"
+// CHECK: @"??_C@_01GAPBHFFA@T?$AA@"
+// CHECK: @"??_C@_01CPLAODJH@S?$AA@"
+// CHECK: @"??_C@_01DGKLNCNG@R?$AA@"
+// CHECK: @"??_C@_01BNIGIBBF@Q?$AA@"
+// CHECK: @"??_C@_01EJNLAFE@P?$AA@"
+// CHECK: @"??_C@_01MJMHLOMK@O?$AA@"
+// CHECK: @"??_C@_01NANMIPIL@N?$AA@"
+// CHECK: @"??_C@_01PLPBNMEI@M?$AA@"
+// CHECK: @"??_C@_01OCOKONAJ@L?$AA@"
+// CHECK: @"??_C@_01KNKLHLMO@K?$AA@"
+// CHECK: @"??_C@_01LELAEKIP@J?$AA@"
+// CHECK: @"??_C@_01JPJNBJEM@I?$AA@"
+// CHECK: @"??_C@_01IGIGCIAN@H?$AA@"
+// CHECK: @"??_C@_01BBODEMC@G?$AA@"
+// CHECK: @"??_C@_01BIAFAFID@F?$AA@"
+// CHECK: @"??_C@_01DDCIFGEA@E?$AA@"
+// CHECK: @"??_C@_01CKDDGHAB@D?$AA@"
+// CHECK: @"??_C@_01GFHCPBMG@C?$AA@"
+// CHECK: @"??_C@_01HMGJMAIH@B?$AA@"
+// CHECK: @"??_C@_01FHEEJDEE@A?$AA@"
+// CHECK: @"??_C@_01EOFPKCAF@?$EA?$AA@"
+// CHECK: @"??_C@_01OGPIMHDM@?$DP?$AA@"
+// CHECK: @"??_C@_01PPODPGHN@?$DO?$AA@"
+// CHECK: @"??_C@_01NEMOKFLO@?$DN?$AA@"
+// CHECK: @"??_C@_01MNNFJEPP@?$DM?$AA@"
+// CHECK: @"??_C@_01ICJEACDI@?$DL?$AA@"
+// CHECK: @"??_C@_01JLIPDDHJ@?3?$AA@"
+// CHECK: @"??_C@_01LAKCGALK@9?$AA@"
+// CHECK: @"??_C@_01KJLJFBPL@8?$AA@"
+// CHECK: @"??_C@_01COCBENDE@7?$AA@"
+// CHECK: @"??_C@_01DHDKHMHF@6?$AA@"
+// CHECK: @"??_C@_01BMBHCPLG@5?$AA@"
+// CHECK: @"??_C@_01FAMBOPH@4?$AA@"
+// CHECK: @"??_C@_01EKENIIDA@3?$AA@"
+// CHECK: @"??_C@_01FDFGLJHB@2?$AA@"
+// CHECK: @"??_C@_01HIHLOKLC@1?$AA@"
+// CHECK: @"??_C@_01GBGANLPD@0?$AA@"
+// CHECK: @"??_C@_01KMDKNFGN@?1?$AA@"
+// CHECK: @"??_C@_01LFCBOECM@?4?$AA@"
+// CHECK: @"??_C@_01JOAMLHOP@?9?$AA@"
+// CHECK: @"??_C@_01IHBHIGKO@?0?$AA@"
+// CHECK: @"??_C@_01MIFGBAGJ@?$CL?$AA@"
+// CHECK: @"??_C@_01NBENCBCI@?$CK?$AA@"
+// CHECK: @"??_C@_01PKGAHCOL@?$CJ?$AA@"
+// CHECK: @"??_C@_01ODHLEDKK@?$CI?$AA@"
+// CHECK: @"??_C@_01GEODFPGF@?8?$AA@"
+// CHECK: @"??_C@_01HNPIGOCE@?$CG?$AA@"
+// CHECK: @"??_C@_01FGNFDNOH@?$CF?$AA@"
+// CHECK: @"??_C@_01EPMOAMKG@$?$AA@"
+// CHECK: @"??_C@_01IPJKGB@?$CD?$AA@"
+// CHECK: @"??_C@_01BJJEKLCA@?$CC?$AA@"
+// CHECK: @"??_C@_01DCLJPIOD@?$CB?$AA@"
+// CHECK: @"??_C@_01CLKCMJKC@?5?$AA@"
+// CHECK: @"??_C@_01HDHMODJO@?$BP?$AA@"
+// CHECK: @"??_C@_01GKGHNCNP@?$BO?$AA@"
+// CHECK: @"??_C@_01EBEKIBBM@?$BN?$AA@"
+// CHECK: @"??_C@_01FIFBLAFN@?$BM?$AA@"
+// CHECK: @"??_C@_01BHBACGJK@?$BL?$AA@"
+// CHECK: @"??_C@_01OALBHNL@?$BK?$AA@"
+// CHECK: @"??_C@_01CFCGEEBI@?$BJ?$AA@"
+// CHECK: @"??_C@_01DMDNHFFJ@?$BI?$AA@"
+// CHECK: @"??_C@_01LLKFGJJG@?$BH?$AA@"
+// CHECK: @"??_C@_01KCLOFINH@?$BG?$AA@"
+// CHECK: @"??_C@_01IJJDALBE@?$BF?$AA@"
+// CHECK: @"??_C@_01JAIIDKFF@?$BE?$AA@"
+// CHECK: @"??_C@_01NPMJKMJC@?$BD?$AA@"
+// CHECK: @"??_C@_01MGNCJNND@?$BC?$AA@"
+// CHECK: @"??_C@_01ONPPMOBA@?$BB?$AA@"
+// CHECK: @"??_C@_01PEOEPPFB@?$BA?$AA@"
+// CHECK: @"??_C@_01DJLOPBMP@?$AP?$AA@"
+// CHECK: @"??_C@_01CAKFMAIO@?$AO?$AA@"
+// CHECK: @"??_C@_01LIIJDEN@?$AN?$AA@"
+// CHECK: @"??_C@_01BCJDKCAM@?$AM?$AA@"
+// CHECK: @"??_C@_01FNNCDEML@?$AL?$AA@"
+// CHECK: @"??_C@_01EEMJAFIK@?6?$AA@"
+// CHECK: @"??_C@_01GPOEFGEJ@?7?$AA@"
+// CHECK: @"??_C@_01HGPPGHAI@?$AI?$AA@"
+// CHECK: @"??_C@_01PBGHHLMH@?$AH?$AA@"
+// CHECK: @"??_C@_01OIHMEKIG@?$AG?$AA@"
+// CHECK: @"??_C@_01MDFBBJEF@?$AF?$AA@"
+// CHECK: @"??_C@_01NKEKCIAE@?$AE?$AA@"
+// CHECK: @"??_C@_01JFALLOMD@?$AD?$AA@"
+// CHECK: @"??_C@_01IMBAIPIC@?$AC?$AA@"
+// CHECK: @"??_C@_01KHDNNMEB@?$AB?$AA@"
+// CHECK: @"??_C@_01LOCGONAA@?$AA?$AA@"
+
+const wchar_t *wl9 = L"\t";
+const wchar_t *wl10 = L"\n";
+const wchar_t *wl11 = L"\v";
+const wchar_t *wl32 = L" ";
+const wchar_t *wl33 = L"!";
+const wchar_t *wl34 = L"\"";
+const wchar_t *wl35 = L"#";
+const wchar_t *wl36 = L"$";
+const wchar_t *wl37 = L"%";
+const wchar_t *wl38 = L"&";
+const wchar_t *wl39 = L"'";
+const wchar_t *wl40 = L"(";
+const wchar_t *wl41 = L")";
+const wchar_t *wl42 = L"*";
+const wchar_t *wl43 = L"+";
+const wchar_t *wl44 = L",";
+const wchar_t *wl45 = L"-";
+const wchar_t *wl46 = L".";
+const wchar_t *wl47 = L"/";
+const wchar_t *wl48 = L"0";
+const wchar_t *wl49 = L"1";
+const wchar_t *wl50 = L"2";
+const wchar_t *wl51 = L"3";
+const wchar_t *wl52 = L"4";
+const wchar_t *wl53 = L"5";
+const wchar_t *wl54 = L"6";
+const wchar_t *wl55 = L"7";
+const wchar_t *wl56 = L"8";
+const wchar_t *wl57 = L"9";
+const wchar_t *wl58 = L":";
+const wchar_t *wl59 = L";";
+const wchar_t *wl60 = L"<";
+const wchar_t *wl61 = L"=";
+const wchar_t *wl62 = L">";
+const wchar_t *wl63 = L"?";
+const wchar_t *wl64 = L"@";
+const wchar_t *wl65 = L"A";
+const wchar_t *wl66 = L"B";
+const wchar_t *wl67 = L"C";
+const wchar_t *wl68 = L"D";
+const wchar_t *wl69 = L"E";
+const wchar_t *wl70 = L"F";
+const wchar_t *wl71 = L"G";
+const wchar_t *wl72 = L"H";
+const wchar_t *wl73 = L"I";
+const wchar_t *wl74 = L"J";
+const wchar_t *wl75 = L"K";
+const wchar_t *wl76 = L"L";
+const wchar_t *wl77 = L"M";
+const wchar_t *wl78 = L"N";
+const wchar_t *wl79 = L"O";
+const wchar_t *wl80 = L"P";
+const wchar_t *wl81 = L"Q";
+const wchar_t *wl82 = L"R";
+const wchar_t *wl83 = L"S";
+const wchar_t *wl84 = L"T";
+const wchar_t *wl85 = L"U";
+const wchar_t *wl86 = L"V";
+const wchar_t *wl87 = L"W";
+const wchar_t *wl88 = L"X";
+const wchar_t *wl89 = L"Y";
+const wchar_t *wl90 = L"Z";
+const wchar_t *wl91 = L"[";
+const wchar_t *wl92 = L"\\";
+const wchar_t *wl93 = L"]";
+const wchar_t *wl94 = L"^";
+const wchar_t *wl95 = L"_";
+const wchar_t *wl96 = L"`";
+const wchar_t *wl97 = L"a";
+const wchar_t *wl98 = L"b";
+const wchar_t *wl99 = L"c";
+const wchar_t *wl100 = L"d";
+const wchar_t *wl101 = L"e";
+const wchar_t *wl102 = L"f";
+const wchar_t *wl103 = L"g";
+const wchar_t *wl104 = L"h";
+const wchar_t *wl105 = L"i";
+const wchar_t *wl106 = L"j";
+const wchar_t *wl107 = L"k";
+const wchar_t *wl108 = L"l";
+const wchar_t *wl109 = L"m";
+const wchar_t *wl110 = L"n";
+const wchar_t *wl111 = L"o";
+const wchar_t *wl112 = L"p";
+const wchar_t *wl113 = L"q";
+const wchar_t *wl114 = L"r";
+const wchar_t *wl115 = L"s";
+const wchar_t *wl116 = L"t";
+const wchar_t *wl117 = L"u";
+const wchar_t *wl118 = L"v";
+const wchar_t *wl119 = L"w";
+const wchar_t *wl120 = L"x";
+const wchar_t *wl121 = L"y";
+const wchar_t *wl122 = L"z";
+const wchar_t *wl123 = L"{";
+const wchar_t *wl124 = L"|";
+const wchar_t *wl125 = L"}";
+const wchar_t *wl126 = L"~";
+
+// CHECK: @"??_C@_13KDLDGPGJ@?$AA?7?$AA?$AA@"
+// CHECK: @"??_C@_13LBAGMAIH@?$AA?6?$AA?$AA@"
+// CHECK: @"??_C@_13JLKKHOC@?$AA?$AL?$AA?$AA@"
+// CHECK: @"??_C@_13HOIJIPNN@?$AA?5?$AA?$AA@"
+// CHECK: @"??_C@_13MGDFOILI@?$AA?$CB?$AA?$AA@"
+// CHECK: @"??_C@_13NEIAEHFG@?$AA?$CC?$AA?$AA@"
+// CHECK: @"??_C@_13GMDMCADD@?$AA?$CD?$AA?$AA@"
+// CHECK: @"??_C@_13PBOLBIIK@?$AA$?$AA?$AA@"
+// CHECK: @"??_C@_13EJFHHPOP@?$AA?$CF?$AA?$AA@"
+// CHECK: @"??_C@_13FLOCNAAB@?$AA?$CG?$AA?$AA@"
+// CHECK: @"??_C@_13ODFOLHGE@?$AA?8?$AA?$AA@"
+// CHECK: @"??_C@_13LLDNKHDC@?$AA?$CI?$AA?$AA@"
+// CHECK: @"??_C@_13DIBMAFH@?$AA?$CJ?$AA?$AA@"
+// CHECK: @"??_C@_13BBDEGPLJ@?$AA?$CK?$AA?$AA@"
+// CHECK: @"??_C@_13KJIIAINM@?$AA?$CL?$AA?$AA@"
+// CHECK: @"??_C@_13DEFPDAGF@?$AA?0?$AA?$AA@"
+// CHECK: @"??_C@_13IMODFHAA@?$AA?9?$AA?$AA@"
+// CHECK: @"??_C@_13JOFGPIOO@?$AA?4?$AA?$AA@"
+// CHECK: @"??_C@_13CGOKJPIL@?$AA?1?$AA?$AA@"
+// CHECK: @"??_C@_13COJANIEC@?$AA0?$AA?$AA@"
+// CHECK: @"??_C@_13JGCMLPCH@?$AA1?$AA?$AA@"
+// CHECK: @"??_C@_13IEJJBAMJ@?$AA2?$AA?$AA@"
+// CHECK: @"??_C@_13DMCFHHKM@?$AA3?$AA?$AA@"
+// CHECK: @"??_C@_13KBPCEPBF@?$AA4?$AA?$AA@"
+// CHECK: @"??_C@_13BJEOCIHA@?$AA5?$AA?$AA@"
+// CHECK: @"??_C@_13LPLIHJO@?$AA6?$AA?$AA@"
+// CHECK: @"??_C@_13LDEHOAPL@?$AA7?$AA?$AA@"
+// CHECK: @"??_C@_13OLCEPAKN@?$AA8?$AA?$AA@"
+// CHECK: @"??_C@_13FDJIJHMI@?$AA9?$AA?$AA@"
+// CHECK: @"??_C@_13EBCNDICG@?$AA?3?$AA?$AA@"
+// CHECK: @"??_C@_13PJJBFPED@?$AA?$DL?$AA?$AA@"
+// CHECK: @"??_C@_13GEEGGHPK@?$AA?$DM?$AA?$AA@"
+// CHECK: @"??_C@_13NMPKAAJP@?$AA?$DN?$AA?$AA@"
+// CHECK: @"??_C@_13MOEPKPHB@?$AA?$DO?$AA?$AA@"
+// CHECK: @"??_C@_13HGPDMIBE@?$AA?$DP?$AA?$AA@"
+// CHECK: @"??_C@_13EFKPHINO@?$AA?$EA?$AA?$AA@"
+// CHECK: @"??_C@_13PNBDBPLL@?$AAA?$AA?$AA@"
+// CHECK: @"??_C@_13OPKGLAFF@?$AAB?$AA?$AA@"
+// CHECK: @"??_C@_13FHBKNHDA@?$AAC?$AA?$AA@"
+// CHECK: @"??_C@_13MKMNOPIJ@?$AAD?$AA?$AA@"
+// CHECK: @"??_C@_13HCHBIIOM@?$AAE?$AA?$AA@"
+// CHECK: @"??_C@_13GAMECHAC@?$AAF?$AA?$AA@"
+// CHECK: @"??_C@_13NIHIEAGH@?$AAG?$AA?$AA@"
+// CHECK: @"??_C@_13IABLFADB@?$AAH?$AA?$AA@"
+// CHECK: @"??_C@_13DIKHDHFE@?$AAI?$AA?$AA@"
+// CHECK: @"??_C@_13CKBCJILK@?$AAJ?$AA?$AA@"
+// CHECK: @"??_C@_13JCKOPPNP@?$AAK?$AA?$AA@"
+// CHECK: @"??_C@_13PHJMHGG@?$AAL?$AA?$AA@"
+// CHECK: @"??_C@_13LHMFKAAD@?$AAM?$AA?$AA@"
+// CHECK: @"??_C@_13KFHAAPON@?$AAN?$AA?$AA@"
+// CHECK: @"??_C@_13BNMMGIII@?$AAO?$AA?$AA@"
+// CHECK: @"??_C@_13BFLGCPEB@?$AAP?$AA?$AA@"
+// CHECK: @"??_C@_13KNAKEICE@?$AAQ?$AA?$AA@"
+// CHECK: @"??_C@_13LPLPOHMK@?$AAR?$AA?$AA@"
+// CHECK: @"??_C@_13HADIAKP@?$AAS?$AA?$AA@"
+// CHECK: @"??_C@_13JKNELIBG@?$AAT?$AA?$AA@"
+// CHECK: @"??_C@_13CCGINPHD@?$AAU?$AA?$AA@"
+// CHECK: @"??_C@_13DANNHAJN@?$AAV?$AA?$AA@"
+// CHECK: @"??_C@_13IIGBBHPI@?$AAW?$AA?$AA@"
+// CHECK: @"??_C@_13NAACAHKO@?$AAX?$AA?$AA@"
+// CHECK: @"??_C@_13GILOGAML@?$AAY?$AA?$AA@"
+// CHECK: @"??_C@_13HKALMPCF@?$AAZ?$AA?$AA@"
+// CHECK: @"??_C@_13MCLHKIEA@?$AA?$FL?$AA?$AA@"
+// CHECK: @"??_C@_13FPGAJAPJ@?$AA?2?$AA?$AA@"
+// CHECK: @"??_C@_13OHNMPHJM@?$AA?$FN?$AA?$AA@"
+// CHECK: @"??_C@_13PFGJFIHC@?$AA?$FO?$AA?$AA@"
+// CHECK: @"??_C@_13ENNFDPBH@?$AA_?$AA?$AA@"
+// CHECK: @"??_C@_13OFJNNHOA@?$AA?$GA?$AA?$AA@"
+// CHECK: @"??_C@_13FNCBLAIF@?$AAa?$AA?$AA@"
+// CHECK: @"??_C@_13EPJEBPGL@?$AAb?$AA?$AA@"
+// CHECK: @"??_C@_13PHCIHIAO@?$AAc?$AA?$AA@"
+// CHECK: @"??_C@_13GKPPEALH@?$AAd?$AA?$AA@"
+// CHECK: @"??_C@_13NCEDCHNC@?$AAe?$AA?$AA@"
+// CHECK: @"??_C@_13MAPGIIDM@?$AAf?$AA?$AA@"
+// CHECK: @"??_C@_13HIEKOPFJ@?$AAg?$AA?$AA@"
+// CHECK: @"??_C@_13CACJPPAP@?$AAh?$AA?$AA@"
+// CHECK: @"??_C@_13JIJFJIGK@?$AAi?$AA?$AA@"
+// CHECK: @"??_C@_13IKCADHIE@?$AAj?$AA?$AA@"
+// CHECK: @"??_C@_13DCJMFAOB@?$AAk?$AA?$AA@"
+// CHECK: @"??_C@_13KPELGIFI@?$AAl?$AA?$AA@"
+// CHECK: @"??_C@_13BHPHAPDN@?$AAm?$AA?$AA@"
+// CHECK: @"??_C@_13FECKAND@?$AAn?$AA?$AA@"
+// CHECK: @"??_C@_13LNPOMHLG@?$AAo?$AA?$AA@"
+// CHECK: @"??_C@_13LFIEIAHP@?$AAp?$AA?$AA@"
+// CHECK: @"??_C@_13NDIOHBK@?$AAq?$AA?$AA@"
+// CHECK: @"??_C@_13BPINEIPE@?$AAr?$AA?$AA@"
+// CHECK: @"??_C@_13KHDBCPJB@?$AAs?$AA?$AA@"
+// CHECK: @"??_C@_13DKOGBHCI@?$AAt?$AA?$AA@"
+// CHECK: @"??_C@_13ICFKHAEN@?$AAu?$AA?$AA@"
+// CHECK: @"??_C@_13JAOPNPKD@?$AAv?$AA?$AA@"
+// CHECK: @"??_C@_13CIFDLIMG@?$AAw?$AA?$AA@"
+// CHECK: @"??_C@_13HADAKIJA@?$AAx?$AA?$AA@"
+// CHECK: @"??_C@_13MIIMMPPF@?$AAy?$AA?$AA@"
+// CHECK: @"??_C@_13NKDJGABL@?$AAz?$AA?$AA@"
+// CHECK: @"??_C@_13GCIFAHHO@?$AA?$HL?$AA?$AA@"
+// CHECK: @"??_C@_13PPFCDPMH@?$AA?$HM?$AA?$AA@"
+// CHECK: @"??_C@_13EHOOFIKC@?$AA?$HN?$AA?$AA@"
+// CHECK: @"??_C@_13FFFLPHEM@?$AA?$HO?$AA?$AA@"
+
+const char *LongASCIIString = "012345678901234567890123456789ABCDEF";
+// CHECK: @"??_C@_0CF@LABBIIMO@012345678901234567890123456789AB@"
+const wchar_t *LongWideString = L"012345678901234567890123456789ABCDEF";
+// CHECK: @"??_C@_1EK@KFPEBLPK@?$AA0?$AA1?$AA2?$AA3?$AA4?$AA5?$AA6?$AA7?$AA8?$AA9?$AA0?$AA1?$AA2?$AA3?$AA4?$AA5?$AA6?$AA7?$AA8?$AA9?$AA0?$AA1?$AA2?$AA3?$AA4?$AA5?$AA6?$AA7?$AA8?$AA9?$AAA?$AAB@"
+const wchar_t *UnicodeLiteral = L"\ud7ff";
+// CHECK: @"??_C@_13IIHIAFKH@?W?$PP?$AA?$AA@"
+
+const char *U8Literal = u8"hi";
+// CHECK: @"??_C@_02PCEFGMJL@hi?$AA@"
+const char *LongU8Literal = u8"012345678901234567890123456789ABCDEF";
+// CHECK: @"??_C@_0CF@LABBIIMO@012345678901234567890123456789AB@"
+
+const char16_t *U16Literal = u"hi";
+// CHECK: @"??_C@_05OMLEGLOC@h?$AAi?$AA?$AA?$AA@"
+// Note this starts with o instead of 0. Else LongWideString would have
+// the same initializer and CodeGenModule::ConstantStringMap would map them
+// to the same global with a shared mangling.
+// FIXME: ConstantStringMap probably shouldn't map things with the same data
+// but different manglings to the same variable.
+const char16_t *LongU16Literal = u"o12345678901234567890123456789ABCDEF";
+// CHECK: @"??_C@_0EK@FEAOBHPP@o?$AA1?$AA2?$AA3?$AA4?$AA5?$AA6?$AA7?$AA8?$AA9?$AA0?$AA1?$AA2?$AA3?$AA4?$AA5?$AA@"
+
+const char32_t *U32Literal = U"hi";
+// CHECK: @"??_C@_0M@GFNAJIPG@h?$AA?$AA?$AAi?$AA?$AA?$AA?$AA?$AA?$AA?$AA@"
+const char32_t *LongU32Literal = U"012345678901234567890123456789ABCDEF";
+// CHECK: @"??_C@_0JE@IMHFEDAA@0?$AA?$AA?$AA1?$AA?$AA?$AA2?$AA?$AA?$AA3?$AA?$AA?$AA4?$AA?$AA?$AA5?$AA?$AA?$AA6?$AA?$AA?$AA7?$AA?$AA?$AA@"
+
+// These all have just the right length that the trailing 0 just fits.
+const char *MaxASCIIString = "012345678901234567890123456789A";
+// CHECK: @"??_C@_0CA@NMANGEKF@012345678901234567890123456789A?$AA@"
+const wchar_t *MaxWideString = L"012345678901234567890123456789A";
+// CHECK: @"??_C@_1EA@LJAFPILO@?$AA0?$AA1?$AA2?$AA3?$AA4?$AA5?$AA6?$AA7?$AA8?$AA9?$AA0?$AA1?$AA2?$AA3?$AA4?$AA5?$AA6?$AA7?$AA8?$AA9?$AA0?$AA1?$AA2?$AA3?$AA4?$AA5?$AA6?$AA7?$AA8?$AA9?$AAA?$AA?$AA@"
+const char *MaxU8String = u8"012345678901234567890123456789A";
+// CHECK: @"??_C@_0CA@NMANGEKF@012345678901234567890123456789A?$AA@"
+const char16_t *MaxU16String = u"012345678901234";
+// CHECK: @"??_C@_0CA@NFEFHIFO@0?$AA1?$AA2?$AA3?$AA4?$AA5?$AA6?$AA7?$AA8?$AA9?$AA0?$AA1?$AA2?$AA3?$AA4?$AA?$AA?$AA@"
+const char32_t *MaxU32String = U"0123456";
+// CHECK: @"??_C@_0CA@KFPHPCC@0?$AA?$AA?$AA1?$AA?$AA?$AA2?$AA?$AA?$AA3?$AA?$AA?$AA4?$AA?$AA?$AA5?$AA?$AA?$AA6?$AA?$AA?$AA?$AA?$AA?$AA?$AA@"
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-template-callback.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-template-callback.cpp
new file mode 100644
index 0000000..25e719f
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-template-callback.cpp
@@ -0,0 +1,89 @@
+// RUN: %clang_cc1 -fblocks -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
+
+template<typename Signature>
+class C;
+
+template<typename Ret>
+class C<Ret(void)> {};
+typedef C<void(void)> C0;
+
+template<typename Ret, typename Arg1>
+class C<Ret(Arg1)> {};
+
+template<typename Ret, typename Arg1, typename Arg2>
+class C<Ret(Arg1, Arg2)> {};
+
+C0 callback_void;
+// CHECK: "?callback_void@@3V?$C@$$A6AXXZ@@A"
+
+volatile C0 callback_void_volatile;
+// CHECK: "?callback_void_volatile@@3V?$C@$$A6AXXZ@@C"
+
+class Type {};
+
+C<int(void)> callback_int;
+// CHECK: "?callback_int@@3V?$C@$$A6AHXZ@@A"
+C<Type(void)> callback_Type;
+// CHECK: "?callback_Type@@3V?$C@$$A6A?AVType@@XZ@@A"
+
+C<void(int)> callback_void_int;
+// CHECK: "?callback_void_int@@3V?$C@$$A6AXH@Z@@A"
+C<int(int)> callback_int_int;
+// CHECK: "?callback_int_int@@3V?$C@$$A6AHH@Z@@A"
+C<void(Type)> callback_void_Type;
+// CHECK: "?callback_void_Type@@3V?$C@$$A6AXVType@@@Z@@A"
+
+void foo(C0 c) {}
+// CHECK: "?foo@@YAXV?$C@$$A6AXXZ@@@Z"
+
+// Here be dragons!
+// Let's face the magic of template partial specialization...
+
+void function(C<void(void)>) {}
+// CHECK: "?function@@YAXV?$C@$$A6AXXZ@@@Z"
+
+template<typename Ret> class C<Ret(*)(void)> {};
+void function_pointer(C<void(*)(void)>) {}
+// CHECK: "?function_pointer@@YAXV?$C@P6AXXZ@@@Z"
+
+// Block equivalent to the previous definitions.
+template<typename Ret> class C<Ret(^)(void)> {};
+void block(C<void(^)(void)>) {}
+// CHECK: "?block@@YAXV?$C@P_EAXXZ@@@Z"
+// FYI blocks are not present in MSVS, so we're free to choose the spec.
+
+template<typename T> class C<void (T::*)(void)> {};
+class Z {
+ public:
+ void method() {}
+};
+void member_pointer(C<void (Z::*)(void)>) {}
+// CHECK: "?member_pointer@@YAXV?$C@P8Z@@AEXXZ@@@Z"
+
+template<typename T> void bar(T) {}
+
+void call_bar() {
+ bar<int (*)(int)>(0);
+// CHECK: "??$bar@P6AHH@Z@@YAXP6AHH@Z@Z"
+
+ bar<int (^)(int)>(0);
+// CHECK: "??$bar@P_EAHH@Z@@YAXP_EAHH@Z@Z"
+// FYI blocks are not present in MSVS, so we're free to choose the spec.
+}
+
+template <void (*Fn)()> void WrapFnPtr() { Fn(); }
+template <void (&Fn)()> void WrapFnRef() { Fn(); }
+struct Thing {
+ static void VoidStaticMethod();
+};
+void VoidFn();
+void CallWrapper() {
+ WrapFnPtr<VoidFn>();
+ WrapFnRef<VoidFn>();
+ WrapFnPtr<Thing::VoidStaticMethod>();
+ WrapFnRef<Thing::VoidStaticMethod>();
+}
+// CHECK: call {{.*}} @"??$WrapFnPtr@$1?VoidFn@@YAXXZ@@YAXXZ"
+// CHECK: call {{.*}} @"??$WrapFnRef@$1?VoidFn@@YAXXZ@@YAXXZ"
+// CHECK: call {{.*}} @"??$WrapFnPtr@$1?VoidStaticMethod@Thing@@SAXXZ@@YAXXZ"
+// CHECK: call {{.*}} @"??$WrapFnRef@$1?VoidStaticMethod@Thing@@SAXXZ@@YAXXZ"
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-templates-memptrs-2.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-templates-memptrs-2.cpp
new file mode 100644
index 0000000..e4a608a
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-templates-memptrs-2.cpp
@@ -0,0 +1,60 @@
+// RUN: %clang_cc1 -Wno-microsoft -fms-extensions -fno-rtti -std=c++11 -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
+
+template <typename T, int (T::*)() = nullptr>
+struct J {};
+
+template <typename T, int T::* = nullptr>
+struct K {};
+
+struct __single_inheritance M;
+J<M> m;
+// CHECK-DAG: @"?m@@3U?$J@UM@@$0A@@@A"
+
+K<M> m2;
+// CHECK-DAG: @"?m2@@3U?$K@UM@@$0?0@@A"
+
+struct __multiple_inheritance N;
+J<N> n;
+// CHECK-DAG: @"?n@@3U?$J@UN@@$HA@@@A"
+
+K<N> n2;
+// CHECK-DAG: @"?n2@@3U?$K@UN@@$0?0@@A"
+
+struct __virtual_inheritance O;
+J<O> o;
+// CHECK-DAG: @"?o@@3U?$J@UO@@$IA@A@@@A"
+
+K<O> o2;
+// CHECK-DAG: @"?o2@@3U?$K@UO@@$FA@?0@@A"
+
+struct P;
+J<P> p;
+// CHECK-DAG: @"?p@@3U?$J@UP@@$JA@A@?0@@A"
+
+K<P> p2;
+// CHECK-DAG: @"?p2@@3U?$K@UP@@$GA@A@?0@@A"
+
+#pragma pointers_to_members(full_generality, virtual_inheritance)
+
+struct S {
+ int a, b;
+ void f();
+ virtual void g();
+};
+
+struct GeneralBase {
+ virtual void h();
+};
+struct MostGeneral : S, virtual GeneralBase {
+ virtual void h();
+};
+template <void (MostGeneral::*MP)()>
+struct ClassTemplate {
+ ClassTemplate() {}
+};
+
+template struct ClassTemplate<&MostGeneral::h>;
+
+// Test that we mangle in the vbptr offset, which is 12 here.
+//
+// CHECK: define weak_odr dso_local x86_thiscallcc %struct.ClassTemplate* @"??0?$ClassTemplate@$J??_9MostGeneral@@$BA@AEA@M@3@@QAE@XZ"
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-templates-memptrs.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-templates-memptrs.cpp
new file mode 100644
index 0000000..3078c5a
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-templates-memptrs.cpp
@@ -0,0 +1,155 @@
+// RUN: %clang_cc1 -Wno-microsoft -fno-rtti -std=c++11 -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
+
+struct U;
+static_assert(sizeof(void (U::*)()) == 2 * sizeof(void*) + 2 * sizeof(int), "");
+
+struct A { int a; };
+struct B { int b; };
+struct I { union { struct { int a, b; }; }; };
+
+struct S { int a, b; void f(); virtual void g(); };
+struct M : A, B { int a, b; void f(); virtual void g(); };
+struct V : virtual A { int a, b; void f(); virtual void g(); };
+struct U { int a, b; void f(); virtual void g(); };
+
+struct C { virtual void f(); };
+struct D { virtual void g(); };
+struct O : C, D { virtual void g(); }; // override of non-primary
+
+// Test data member pointers.
+template <typename T, int T::*F>
+int ReadField(T &o) {
+ return F ? o.*F : 0;
+}
+
+// Redeclare some of the classes so that the implicit attribute goes on the most
+// recent redeclaration rather than the definition.
+struct V;
+
+void ReadFields() {
+ A a;
+ I i;
+ S s;
+ M m;
+ V v;
+ U u;
+ ReadField<S, &S::a>(s);
+ ReadField<M, &M::a>(m);
+ ReadField<V, &V::a>(v);
+ ReadField<U, &U::a>(u);
+ ReadField<S, &S::b>(s);
+ ReadField<M, &M::b>(m);
+ ReadField<V, &V::b>(v);
+ ReadField<U, &U::b>(u);
+ ReadField<S, nullptr>(s);
+ ReadField<M, nullptr>(m);
+ ReadField<V, nullptr>(v);
+ ReadField<U, nullptr>(u);
+
+ // Non-polymorphic null data memptr vs first field memptr.
+ ReadField<A, &A::a>(a);
+ ReadField<A, nullptr>(a);
+
+ // Indirect fields injected from anonymous unions and structs
+ ReadField<I, &I::a>(i);
+ ReadField<I, &I::b>(i);
+}
+
+// CHECK-LABEL: define {{.*}}ReadFields
+// CHECK: call {{.*}} @"??$ReadField@US@@$03@@YAHAAUS@@@Z"
+// CHECK: call {{.*}} @"??$ReadField@UM@@$0M@@@YAHAAUM@@@Z"
+// CHECK: call {{.*}} @"??$ReadField@UV@@$F7A@@@YAHAAUV@@@Z"
+// CHECK: call {{.*}} @"??$ReadField@UU@@$G3A@A@@@YAHAAUU@@@Z"
+// CHECK: call {{.*}} @"??$ReadField@US@@$07@@YAHAAUS@@@Z"
+// CHECK: call {{.*}} @"??$ReadField@UM@@$0BA@@@YAHAAUM@@@Z"
+// CHECK: call {{.*}} @"??$ReadField@UV@@$FM@A@@@YAHAAUV@@@Z"
+// CHECK: call {{.*}} @"??$ReadField@UU@@$G7A@A@@@YAHAAUU@@@Z"
+
+// MSVC mangles null member pointers in function templates wrong, but it gets
+// them right in class templates.
+// CHECK: call {{.*}} @"??$ReadField@US@@$0A@@@YAHAAUS@@@Z"
+// CHECK: call {{.*}} @"??$ReadField@UM@@$0A@@@YAHAAUM@@@Z"
+// CHECK: call {{.*}} @"??$ReadField@UV@@$0A@@@YAHAAUV@@@Z"
+// CHECK: call {{.*}} @"??$ReadField@UU@@$0A@@@YAHAAUU@@@Z"
+
+// Non-polymorphic null data memptr vs first field memptr. MSVC mangles these
+// the same.
+// CHECK: call {{.*}} @"??$ReadField@UA@@$0A@@@YAHAAUA@@@Z"
+// CHECK: call {{.*}} @"??$ReadField@UA@@$0?0@@YAHAAUA@@@Z"
+
+// Indirect fields are handled as-if they were simply members of their enclosing
+// record.
+// CHECK: call {{.*}} @"??$ReadField@UI@@$0A@@@YAHAAUI@@@Z"
+// CHECK: call {{.*}} @"??$ReadField@UI@@$03@@YAHAAUI@@@Z"
+
+// Test member function pointers.
+template <typename T, void (T::*MFP)()>
+void CallMethod(T &o) {
+ (o.*MFP)();
+}
+
+void CallMethods() {
+ S s;
+ M m;
+ V v;
+ U u;
+ O o;
+
+ // Non-virtual methods.
+ CallMethod<S, &S::f>(s);
+ CallMethod<M, &M::f>(m);
+ CallMethod<V, &V::f>(v);
+ CallMethod<U, &U::f>(u);
+
+ // Virtual methods requiring thunk mangling.
+ CallMethod<S, &S::g>(s);
+ CallMethod<M, &M::g>(m);
+ CallMethod<V, &V::g>(v);
+ CallMethod<U, &U::g>(u);
+
+ // A member pointer for a non-primary vbase will have a non-zero this
+ // adjustment.
+ CallMethod<O, &O::g>(o);
+
+ // Null member pointers.
+ CallMethod<S, nullptr>(s);
+ CallMethod<M, nullptr>(m);
+ CallMethod<V, nullptr>(v);
+ CallMethod<U, nullptr>(u);
+}
+
+// CHECK-LABEL: define {{.*}}CallMethods
+// CHECK: call {{.*}} @"??$CallMethod@US@@$1?f@1@QAEXXZ@@YAXAAUS@@@Z"
+// CHECK: call {{.*}} @"??$CallMethod@UM@@$H?f@1@QAEXXZA@@@YAXAAUM@@@Z"
+// CHECK: call {{.*}} @"??$CallMethod@UV@@$I?f@1@QAEXXZA@A@@@YAXAAUV@@@Z"
+// CHECK: call {{.*}} @"??$CallMethod@UU@@$J?f@1@QAEXXZA@A@A@@@YAXAAUU@@@Z"
+
+// PR17034: MSVC reuses the same thunk for every virtual g method because they
+// are all at vftable offset zero. They then mangle the name of the first thunk
+// created into the name of the template instantiation, which is definitely a
+// bug. We don't follow them here. Instead of ?_91@ backref below, they would
+// get ?_9S@@ in every instantiation after the first.
+
+// CHECK: call {{.*}} @"??$CallMethod@US@@$1??_91@$BA@AE@@YAXAAUS@@@Z"
+// CHECK: call {{.*}} @"??$CallMethod@UM@@$H??_91@$BA@AEA@@@YAXAAUM@@@Z"
+// CHECK: call {{.*}} @"??$CallMethod@UV@@$I??_91@$BA@AEA@A@@@YAXAAUV@@@Z"
+// CHECK: call {{.*}} @"??$CallMethod@UU@@$J??_91@$BA@AEA@A@A@@@YAXAAUU@@@Z"
+
+// CHECK: call {{.*}} @"??$CallMethod@UO@@$H??_91@$BA@AE3@@YAXAAUO@@@Z"
+
+// CHECK: call {{.*}} @"??$CallMethod@US@@$0A@@@YAXAAUS@@@Z"
+// CHECK: call {{.*}} @"??$CallMethod@UM@@$0A@@@YAXAAUM@@@Z"
+// CHECK: call {{.*}} @"??$CallMethod@UV@@$0A@@@YAXAAUV@@@Z"
+// CHECK: call {{.*}} @"??$CallMethod@UU@@$0A@@@YAXAAUU@@@Z"
+
+namespace NegativeNVOffset {
+struct A {};
+struct B : virtual A {};
+struct C : B {
+ virtual void f();
+};
+}
+
+template void CallMethod<NegativeNVOffset::C, &NegativeNVOffset::C::f>(NegativeNVOffset::C &);
+
+// CHECK-LABEL: define {{.*}} @"??$CallMethod@UC@NegativeNVOffset@@$I??_912@$BA@AEPPPPPPPM@A@@@YAXAAUC@NegativeNVOffset@@@Z"
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-templates.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-templates.cpp
new file mode 100644
index 0000000..469a23a
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-templates.cpp
@@ -0,0 +1,312 @@
+// RUN: %clang_cc1 -std=c++11 -fms-compatibility-version=19 -emit-llvm %s -o - -fms-extensions -fdelayed-template-parsing -triple=i386-pc-win32 | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -fms-compatibility-version=19 -emit-llvm %s -o - -fms-extensions -fdelayed-template-parsing -triple=x86_64-pc-win32 | FileCheck -check-prefix X64 %s
+// RUN: %clang_cc1 -std=c++17 -fms-compatibility-version=19 -emit-llvm %s -o - -fms-extensions -fdelayed-template-parsing -triple=i386-pc-win32 | FileCheck %s
+// RUN: %clang_cc1 -std=c++17 -fms-compatibility-version=19 -emit-llvm %s -o - -fms-extensions -fdelayed-template-parsing -triple=x86_64-pc-win32 | FileCheck -check-prefix X64 %s
+
+template<typename T>
+class Class {
+ public:
+ Class() {}
+};
+
+class Typename { };
+
+template<typename T>
+class Nested { };
+
+template<bool flag>
+class BoolTemplate {
+ public:
+ BoolTemplate() {}
+};
+
+template<int param>
+class IntTemplate {
+ public:
+ IntTemplate() {}
+};
+
+template<unsigned param>
+class UnsignedIntTemplate {
+public:
+ UnsignedIntTemplate() {}
+};
+
+template<long long param>
+class LongLongTemplate {
+ public:
+ LongLongTemplate() {}
+};
+
+template<unsigned long long param>
+class UnsignedLongLongTemplate {
+ public:
+ UnsignedLongLongTemplate() {}
+};
+
+template<>
+class BoolTemplate<true> {
+ public:
+ BoolTemplate() {}
+ template<class T> void Foo(T arg) {}
+};
+
+void template_mangling() {
+ Class<Typename> c1;
+// CHECK: call {{.*}} @"??0?$Class@VTypename@@@@QAE@XZ"
+// X64: call {{.*}} @"??0?$Class@VTypename@@@@QEAA@XZ"
+
+ Class<const Typename> c1_const;
+// CHECK: call {{.*}} @"??0?$Class@$$CBVTypename@@@@QAE@XZ"
+// X64: call {{.*}} @"??0?$Class@$$CBVTypename@@@@QEAA@XZ"
+ Class<volatile Typename> c1_volatile;
+// CHECK: call {{.*}} @"??0?$Class@$$CCVTypename@@@@QAE@XZ"
+// X64: call {{.*}} @"??0?$Class@$$CCVTypename@@@@QEAA@XZ"
+ Class<const volatile Typename> c1_cv;
+// CHECK: call {{.*}} @"??0?$Class@$$CDVTypename@@@@QAE@XZ"
+// X64: call {{.*}} @"??0?$Class@$$CDVTypename@@@@QEAA@XZ"
+
+ Class<Nested<Typename> > c2;
+// CHECK: call {{.*}} @"??0?$Class@V?$Nested@VTypename@@@@@@QAE@XZ"
+// X64: call {{.*}} @"??0?$Class@V?$Nested@VTypename@@@@@@QEAA@XZ"
+
+ Class<int * const> c_intpc;
+// CHECK: call {{.*}} @"??0?$Class@QAH@@QAE@XZ"
+// X64: call {{.*}} @"??0?$Class@QEAH@@QEAA@XZ"
+ Class<int()> c_ft;
+// CHECK: call {{.*}} @"??0?$Class@$$A6AHXZ@@QAE@XZ"
+// X64: call {{.*}} @"??0?$Class@$$A6AHXZ@@QEAA@XZ"
+ Class<int[]> c_inti;
+// CHECK: call {{.*}} @"??0?$Class@$$BY0A@H@@QAE@XZ"
+// X64: call {{.*}} @"??0?$Class@$$BY0A@H@@QEAA@XZ"
+ Class<int[5]> c_int5;
+// CHECK: call {{.*}} @"??0?$Class@$$BY04H@@QAE@XZ"
+// X64: call {{.*}} @"??0?$Class@$$BY04H@@QEAA@XZ"
+ Class<const int[5]> c_intc5;
+// CHECK: call {{.*}} @"??0?$Class@$$BY04$$CBH@@QAE@XZ"
+// X64: call {{.*}} @"??0?$Class@$$BY04$$CBH@@QEAA@XZ"
+ Class<int * const[5]> c_intpc5;
+// CHECK: call {{.*}} @"??0?$Class@$$BY04QAH@@QAE@XZ"
+// X64: call {{.*}} @"??0?$Class@$$BY04QEAH@@QEAA@XZ"
+
+ BoolTemplate<false> _false;
+// CHECK: call {{.*}} @"??0?$BoolTemplate@$0A@@@QAE@XZ"
+// X64: call {{.*}} @"??0?$BoolTemplate@$0A@@@QEAA@XZ"
+
+ BoolTemplate<true> _true;
+ // PR13158
+ _true.Foo(1);
+// CHECK: call {{.*}} @"??0?$BoolTemplate@$00@@QAE@XZ"
+// X64: call {{.*}} @"??0?$BoolTemplate@$00@@QEAA@XZ"
+// CHECK: call {{.*}} @"??$Foo@H@?$BoolTemplate@$00@@QAEXH@Z"
+// X64: call {{.*}} @"??$Foo@H@?$BoolTemplate@$00@@QEAAXH@Z"
+
+ IntTemplate<0> zero;
+// CHECK: call {{.*}} @"??0?$IntTemplate@$0A@@@QAE@XZ"
+// X64: call {{.*}} @"??0?$IntTemplate@$0A@@@QEAA@XZ"
+
+ IntTemplate<5> five;
+// CHECK: call {{.*}} @"??0?$IntTemplate@$04@@QAE@XZ"
+// X64: call {{.*}} @"??0?$IntTemplate@$04@@QEAA@XZ"
+
+ IntTemplate<11> eleven;
+// CHECK: call {{.*}} @"??0?$IntTemplate@$0L@@@QAE@XZ"
+// X64: call {{.*}} @"??0?$IntTemplate@$0L@@@QEAA@XZ"
+
+ IntTemplate<256> _256;
+// CHECK: call {{.*}} @"??0?$IntTemplate@$0BAA@@@QAE@XZ"
+// X64: call {{.*}} @"??0?$IntTemplate@$0BAA@@@QEAA@XZ"
+
+ IntTemplate<513> _513;
+// CHECK: call {{.*}} @"??0?$IntTemplate@$0CAB@@@QAE@XZ"
+// X64: call {{.*}} @"??0?$IntTemplate@$0CAB@@@QEAA@XZ"
+
+ IntTemplate<1026> _1026;
+// CHECK: call {{.*}} @"??0?$IntTemplate@$0EAC@@@QAE@XZ"
+// X64: call {{.*}} @"??0?$IntTemplate@$0EAC@@@QEAA@XZ"
+
+ IntTemplate<65535> ffff;
+// CHECK: call {{.*}} @"??0?$IntTemplate@$0PPPP@@@QAE@XZ"
+// X64: call {{.*}} @"??0?$IntTemplate@$0PPPP@@@QEAA@XZ"
+
+ IntTemplate<-1> neg_1;
+// CHECK: call {{.*}} @"??0?$IntTemplate@$0?0@@QAE@XZ"
+// X64: call {{.*}} @"??0?$IntTemplate@$0?0@@QEAA@XZ"
+ IntTemplate<-9> neg_9;
+// CHECK: call {{.*}} @"??0?$IntTemplate@$0?8@@QAE@XZ"
+// X64: call {{.*}} @"??0?$IntTemplate@$0?8@@QEAA@XZ"
+ IntTemplate<-10> neg_10;
+// CHECK: call {{.*}} @"??0?$IntTemplate@$0?9@@QAE@XZ"
+// X64: call {{.*}} @"??0?$IntTemplate@$0?9@@QEAA@XZ"
+ IntTemplate<-11> neg_11;
+// CHECK: call {{.*}} @"??0?$IntTemplate@$0?L@@@QAE@XZ"
+// X64: call {{.*}} @"??0?$IntTemplate@$0?L@@@QEAA@XZ"
+
+ UnsignedIntTemplate<4294967295> ffffffff;
+// CHECK: call {{.*}} @"??0?$UnsignedIntTemplate@$0PPPPPPPP@@@QAE@XZ"
+// X64: call {{.*}} @"??0?$UnsignedIntTemplate@$0PPPPPPPP@@@QEAA@XZ"
+
+ LongLongTemplate<-9223372036854775807LL-1LL> int64_min;
+// CHECK: call {{.*}} @"??0?$LongLongTemplate@$0?IAAAAAAAAAAAAAAA@@@QAE@XZ"
+// X64: call {{.*}} @"??0?$LongLongTemplate@$0?IAAAAAAAAAAAAAAA@@@QEAA@XZ"
+ LongLongTemplate<9223372036854775807LL> int64_max;
+// CHECK: call {{.*}} @"??0?$LongLongTemplate@$0HPPPPPPPPPPPPPPP@@@QAE@XZ"
+// X64: call {{.*}} @"??0?$LongLongTemplate@$0HPPPPPPPPPPPPPPP@@@QEAA@XZ"
+ UnsignedLongLongTemplate<18446744073709551615ULL> uint64_max;
+// CHECK: call {{.*}} @"??0?$UnsignedLongLongTemplate@$0?0@@QAE@XZ"
+// X64: call {{.*}} @"??0?$UnsignedLongLongTemplate@$0?0@@QEAA@XZ"
+ UnsignedLongLongTemplate<(unsigned long long)-1> uint64_neg_1;
+// CHECK: call {{.*}} @"??0?$UnsignedLongLongTemplate@$0?0@@QAE@XZ"
+// X64: call {{.*}} @"??0?$UnsignedLongLongTemplate@$0?0@@QEAA@XZ"
+}
+
+namespace space {
+ template<class T> const T& foo(const T& l) { return l; }
+}
+// CHECK: "??$foo@H@space@@YAABHABH@Z"
+// X64: "??$foo@H@space@@YAAEBHAEBH@Z"
+
+void use() {
+ space::foo(42);
+}
+
+// PR13455
+typedef void (*FunctionPointer)(void);
+
+template <FunctionPointer function>
+void FunctionPointerTemplate() {
+ function();
+}
+
+void spam() {
+ FunctionPointerTemplate<spam>();
+// CHECK: "??$FunctionPointerTemplate@$1?spam@@YAXXZ@@YAXXZ"
+// X64: "??$FunctionPointerTemplate@$1?spam@@YAXXZ@@YAXXZ"
+}
+
+// Unlike Itanium, there is no character code to indicate an argument pack.
+// Tested with MSVC 2013, the first version which supports variadic templates.
+
+template <typename ...Ts> void variadic_fn_template(const Ts &...args);
+template <typename... Ts, typename... Us>
+void multi_variadic_fn(Ts... ts, Us... us);
+template <typename... Ts, typename C, typename... Us>
+void multi_variadic_mixed(Ts... ts, C c, Us... us);
+void variadic_fn_instantiate() {
+ variadic_fn_template(0, 1, 3, 4);
+ variadic_fn_template(0, 1, 'a', "b");
+
+ // Directlly consecutive packs are separated by $$Z...
+ multi_variadic_fn<int, int>(1, 2, 3, 4, 5);
+ multi_variadic_fn<int, int, int>(1, 2, 3, 4, 5);
+
+ // ...but not if another template parameter is between them.
+ multi_variadic_mixed<int, int>(1, 2, 3);
+ multi_variadic_mixed<int, int>(1, 2, 3, 4);
+}
+// CHECK: "??$variadic_fn_template@HHHH@@YAXABH000@Z"
+// X64: "??$variadic_fn_template@HHHH@@YAXAEBH000@Z"
+// CHECK: "??$variadic_fn_template@HHD$$BY01D@@YAXABH0ABDAAY01$$CBD@Z"
+// X64: "??$variadic_fn_template@HHD$$BY01D@@YAXAEBH0AEBDAEAY01$$CBD@Z"
+// CHECK: "??$multi_variadic_fn@HH$$ZHHH@@YAXHHHHH@Z"
+// X64: "??$multi_variadic_fn@HH$$ZHHH@@YAXHHHHH@Z"
+// CHECK: "??$multi_variadic_fn@HHH$$ZHH@@YAXHHHHH@Z"
+// X64: "??$multi_variadic_fn@HHH$$ZHH@@YAXHHHHH@Z"
+// CHECK: "??$multi_variadic_mixed@HHH$$V@@YAXHHH@Z"
+// X64: "??$multi_variadic_mixed@HHH$$V@@YAXHHH@Z"
+// CHECK: "??$multi_variadic_mixed@HHHH@@YAXHHHH@Z"
+// X64: "??$multi_variadic_mixed@HHHH@@YAXHHHH@Z"
+
+template <typename ...Ts>
+struct VariadicClass {
+ VariadicClass() { }
+ int x;
+};
+void variadic_class_instantiate() {
+ VariadicClass<int, char, bool> a;
+ VariadicClass<bool, char, int> b;
+}
+// CHECK: call {{.*}} @"??0?$VariadicClass@HD_N@@QAE@XZ"
+// CHECK: call {{.*}} @"??0?$VariadicClass@_NDH@@QAE@XZ"
+
+template <typename T>
+struct Second {};
+
+template <typename T, template <class> class>
+struct Type {};
+
+template <template <class> class T>
+struct Type2 {};
+
+template <template <class> class T, bool B>
+struct Thing;
+
+template <template <class> class T>
+struct Thing<T, false> { };
+
+template <template <class> class T>
+struct Thing<T, true> { };
+
+void template_template_fun(Type<Thing<Second, true>, Second>) { }
+// CHECK: "?template_template_fun@@YAXU?$Type@U?$Thing@USecond@@$00@@USecond@@@@@Z"
+
+template <typename T>
+void template_template_specialization();
+
+template <>
+void template_template_specialization<void (Type<Thing<Second, true>, Second>)>() {
+}
+// CHECK: "??$template_template_specialization@$$A6AXU?$Type@U?$Thing@USecond@@$00@@USecond@@@@@Z@@YAXXZ"
+
+// PR16788
+template <decltype(nullptr)> struct S1 {};
+void f(S1<nullptr>) {}
+// CHECK: "?f@@YAXU?$S1@$0A@@@@Z"
+
+struct record {
+ int first;
+ int second;
+};
+template <const record &>
+struct type1 {
+};
+extern const record inst;
+void recref(type1<inst>) {}
+// CHECK: "?recref@@YAXU?$type1@$E?inst@@3Urecord@@B@@@Z"
+
+struct _GUID {};
+struct __declspec(uuid("{12345678-1234-1234-1234-1234567890aB}")) uuid;
+
+template <typename T, const _GUID *G = &__uuidof(T)>
+struct UUIDType1 {};
+
+template <typename T, const _GUID &G = __uuidof(T)>
+struct UUIDType2 {};
+
+void fun(UUIDType1<uuid> a) {}
+// CHECK: "?fun@@YAXU?$UUIDType1@Uuuid@@$1?_GUID_12345678_1234_1234_1234_1234567890ab@@3U__s_GUID@@B@@@Z"
+void fun(UUIDType2<uuid> b) {}
+// CHECK: "?fun@@YAXU?$UUIDType2@Uuuid@@$E?_GUID_12345678_1234_1234_1234_1234567890ab@@3U__s_GUID@@B@@@Z"
+
+template <typename T> struct TypeWithFriendDefinition {
+ friend void FunctionDefinedWithInjectedName(TypeWithFriendDefinition<T>) {}
+};
+// CHECK: call {{.*}} @"?FunctionDefinedWithInjectedName@@YAXU?$TypeWithFriendDefinition@H@@@Z"
+void CallFunctionDefinedWithInjectedName() {
+ FunctionDefinedWithInjectedName(TypeWithFriendDefinition<int>());
+}
+// CHECK: @"?FunctionDefinedWithInjectedName@@YAXU?$TypeWithFriendDefinition@H@@@Z"
+
+// We need to be able to feed GUIDs through a couple rounds of template
+// substitution.
+template <const _GUID *G>
+struct UUIDType3 {
+ void foo() {}
+};
+template <const _GUID *G>
+struct UUIDType4 : UUIDType3<G> {
+ void bar() { UUIDType4::foo(); }
+};
+template struct UUIDType4<&__uuidof(uuid)>;
+// CHECK: "?bar@?$UUIDType4@$1?_GUID_12345678_1234_1234_1234_1234567890ab@@3U__s_GUID@@B@@QAEXXZ"
+// CHECK: "?foo@?$UUIDType3@$1?_GUID_12345678_1234_1234_1234_1234567890ab@@3U__s_GUID@@B@@QAEXXZ"
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-thunks-covariant.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-thunks-covariant.cpp
new file mode 100644
index 0000000..47b1a38
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-thunks-covariant.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -fno-rtti-data -std=c++11 -fms-extensions -emit-llvm %s -o - -triple=x86_64-pc-win32 -fms-compatibility-version=19.00 | FileCheck %s --check-prefix=CHECK
+
+namespace t1 {
+struct A {
+public:
+ virtual ~A();
+ virtual A *f();
+};
+struct B {
+public:
+ virtual ~B();
+
+private:
+ virtual B *f();
+};
+struct C : A, B {
+ virtual ~C();
+
+protected:
+ virtual C *f();
+};
+C c;
+}
+// Main external C::f impl:
+// CHECK-DAG: "?f@C@t1@@MEAAPEAU12@XZ"
+// New slot in C's vftable for B, returns C* directly:
+// CHECK-DAG: "?f@C@t1@@O7EAAPEAU12@XZ"
+// Return-adjusting thunk in C's vftable for B:
+// CHECK-DAG: "?f@C@t1@@W7EAAPEAUB@2@XZ"
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-vector-types.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-vector-types.cpp
new file mode 100644
index 0000000..c2461a3
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-ms-vector-types.cpp
@@ -0,0 +1,102 @@
+// RUN: %clang_cc1 -fms-extensions -fcxx-exceptions -ffreestanding -target-feature +avx -emit-llvm %s -o - -triple=i686-pc-win32 | FileCheck %s
+
+#include <xmmintrin.h>
+#include <emmintrin.h>
+#include <immintrin.h>
+
+void thow(int i) {
+ switch (i) {
+ case 0: throw __m64();
+ // CHECK: ??_R0?AT__m64@@@8
+ // CHECK: _CT??_R0?AT__m64@@@88
+ // CHECK: _CTA1?AT__m64@@
+ // CHECK: _TI1?AT__m64@@
+ case 1: throw __m128();
+ // CHECK: ??_R0?AT__m128@@@8
+ // CHECK: _CT??_R0?AT__m128@@@816
+ // CHECK: _CTA1?AT__m128@@
+ // CHECK: _TI1?AT__m128@@
+ case 2: throw __m128d();
+ // CHECK: ??_R0?AU__m128d@@@8
+ // CHECK: _CT??_R0?AU__m128d@@@816
+ // CHECK: _CTA1?AU__m128d@@
+ // CHECK: _TI1?AU__m128d@@
+ case 3: throw __m128i();
+ // CHECK: ??_R0?AT__m128i@@@8
+ // CHECK: _CT??_R0?AT__m128i@@@816
+ // CHECK: _CTA1?AT__m128i@@
+ // CHECK: _TI1?AT__m128i@@
+ case 4: throw __m256();
+ // CHECK: ??_R0?AT__m256@@@8
+ // CHECK: _CT??_R0?AT__m256@@@832
+ // CHECK: _CTA1?AT__m256@@
+ // CHECK: _TI1?AT__m256@@
+ case 5: throw __m256d();
+ // CHECK: ??_R0?AU__m256d@@@8
+ // CHECK: _CT??_R0?AU__m256d@@@832
+ // CHECK: _CTA1?AU__m256d@@
+ // CHECK: _TI1?AU__m256d@@
+ case 6: throw __m256i();
+ // CHECK: ??_R0?AT__m256@@@8
+ // CHECK: _CT??_R0?AT__m256@@@832
+ // CHECK: _CTA1?AT__m256@@
+ // CHECK: _TI1?AT__m256@@
+ }
+}
+
+void foo64(__m64) {}
+// CHECK: define dso_local void @"?foo64@@YAXT__m64@@@Z"
+
+__m64 rfoo64() { return __m64(); }
+// CHECK: define dso_local <1 x i64> @"?rfoo64@@YA?AT__m64@@XZ"
+
+void foo128(__m128) {}
+// CHECK: define dso_local void @"?foo128@@YAXT__m128@@@Z"
+
+const __m128 rfoo128() { return __m128(); }
+// CHECK: define dso_local <4 x float> @"?rfoo128@@YA?BT__m128@@XZ"
+
+void foo128d(__m128d) {}
+// CHECK: define dso_local void @"?foo128d@@YAXU__m128d@@@Z"
+
+volatile __m128d rfoo128d() { return __m128d(); }
+// CHECK: define dso_local <2 x double> @"?rfoo128d@@YA?CU__m128d@@XZ"
+
+void foo128i(__m128i) {}
+// CHECK: define dso_local void @"?foo128i@@YAXT__m128i@@@Z"
+
+const volatile __m128i rfoo128i() { return __m128i(); }
+// CHECK: define dso_local <2 x i64> @"?rfoo128i@@YA?DT__m128i@@XZ"
+
+void foo256(__m256) {}
+// CHECK: define dso_local void @"?foo256@@YAXT__m256@@@Z"
+
+__m256 rfoo256() { return __m256(); }
+// CHECK: define dso_local <8 x float> @"?rfoo256@@YA?AT__m256@@XZ"
+
+void foo256d(__m256d) {}
+// CHECK: define dso_local void @"?foo256d@@YAXU__m256d@@@Z"
+
+__m256d rfoo256d() { return __m256d(); }
+// CHECK: define dso_local <4 x double> @"?rfoo256d@@YA?AU__m256d@@XZ"
+
+void foo256i(__m256i) {}
+// CHECK: define dso_local void @"?foo256i@@YAXT__m256i@@@Z"
+
+__m256i rfoo256i() { return __m256i(); }
+// CHECK: define dso_local <4 x i64> @"?rfoo256i@@YA?AT__m256i@@XZ"
+
+// We have a custom mangling for vector types not standardized by Intel.
+void foov8hi(__v8hi) {}
+// CHECK: define dso_local void @"?foov8hi@@YAXT?$__vector@F$07@__clang@@@Z"
+
+typedef __attribute__((ext_vector_type(4))) int vi4b;
+void foovi4b(vi4b) {}
+// CHECK: define dso_local void @"?foovi4b@@YAXT?$__vector@H$03@__clang@@@Z"
+
+typedef float __attribute__((__ext_vector_type__(3))) vf3;
+void foovf3(vf3) {}
+// CHECK: define dso_local void @"?foovf3@@YAXT?$__vector@M$02@__clang@@@Z"
+
+// Clang does not support vectors of complex types, so we can't test the
+// mangling of them.
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-ms.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-ms.cpp
new file mode 100644
index 0000000..0175b96
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-ms.cpp
@@ -0,0 +1,500 @@
+// RUN: %clang_cc1 -fblocks -emit-llvm %s -o - -triple=i386-pc-win32 -std=c++98 | FileCheck %s
+// RUN: %clang_cc1 -fblocks -emit-llvm %s -o - -triple=x86_64-pc-win32 -std=c++98| FileCheck -check-prefix X64 %s
+// RUN: %clang_cc1 -fblocks -emit-llvm %s -o - -triple=aarch64-pc-win32 -std=c++98 -DARM | FileCheck -check-prefixes=X64,ARM %s
+
+int a;
+// CHECK-DAG: @"?a@@3HA"
+
+extern "C++" {
+static int __attribute__((used)) ignore_transparent_context;
+// CHECK-DAG: @ignore_transparent_context
+}
+
+namespace N {
+ int b;
+// CHECK-DAG: @"?b@N@@3HA"
+
+ namespace {
+ int anonymous;
+// CHECK-DAG: @"?anonymous@?A0x{{[^@]*}}@N@@3HA"
+ }
+}
+
+static int c;
+// CHECK-DAG: @c
+
+int _c(void) {return N::anonymous + c;}
+// CHECK-DAG: @"?_c@@YAHXZ"
+// X64-DAG: @"?_c@@YAHXZ"
+
+const int &NeedsReferenceTemporary = 2;
+// CHECK-DAG: @"?NeedsReferenceTemporary@@3ABHB" = dso_local constant i32* @"?$RT1@NeedsReferenceTemporary@@3ABHB"
+// X64-DAG: @"?NeedsReferenceTemporary@@3AEBHEB" = dso_local constant i32* @"?$RT1@NeedsReferenceTemporary@@3AEBHEB"
+
+class foo {
+ static const short d;
+// CHECK-DAG: @"?d@foo@@0FB"
+protected:
+ static volatile long e;
+// CHECK-DAG: @"?e@foo@@1JC"
+public:
+ static const volatile char f;
+// CHECK-DAG: @"?f@foo@@2DD"
+ int operator+(int a);
+ foo(){}
+// CHECK-DAG: @"??0foo@@QAE@XZ"
+// X64-DAG: @"??0foo@@QEAA@XZ"
+
+ ~foo(){}
+// CHECK-DAG: @"??1foo@@QAE@XZ"
+// X64-DAG: @"??1foo@@QEAA@XZ
+
+ foo(int i){}
+// CHECK-DAG: @"??0foo@@QAE@H@Z"
+// X64-DAG: @"??0foo@@QEAA@H@Z"
+
+ foo(char *q){}
+// CHECK-DAG: @"??0foo@@QAE@PAD@Z"
+// X64-DAG: @"??0foo@@QEAA@PEAD@Z"
+
+ static foo* static_method() { return 0; }
+
+}f,s1(1),s2((char*)0);
+
+typedef foo (foo2);
+
+struct bar {
+ static int g;
+};
+
+union baz {
+ int a;
+ char b;
+ double c;
+};
+
+enum quux {
+ qone,
+ qtwo,
+ qthree
+};
+
+foo bar() { return foo(); }
+// CHECK-DAG: @"?bar@@YA?AVfoo@@XZ"
+// X64-DAG: @"?bar@@YA?AVfoo@@XZ"
+
+int foo::operator+(int a) {
+// CHECK-DAG: @"??Hfoo@@QAEHH@Z"
+// X64-DAG: @"??Hfoo@@QEAAHH@Z"
+
+ foo::static_method();
+// CHECK-DAG: @"?static_method@foo@@SAPAV1@XZ"
+// X64-DAG: @"?static_method@foo@@SAPEAV1@XZ"
+ bar();
+ return a;
+}
+
+const short foo::d = 0;
+volatile long foo::e;
+const volatile char foo::f = 'C';
+
+int bar::g;
+// CHECK-DAG: @"?g@bar@@2HA"
+
+extern int * const h1 = &a;
+// CHECK-DAG: @"?h1@@3QAHA"
+extern const int * const h2 = &a;
+// CHECK-DAG: @"?h2@@3QBHB"
+extern int * const __restrict h3 = &a;
+// CHECK-DAG: @"?h3@@3QIAHIA"
+// X64-DAG: @"?h3@@3QEIAHEIA"
+
+int i[10][20];
+// CHECK-DAG: @"?i@@3PAY0BE@HA"
+
+typedef int (*FunT)(int, int);
+FunT FunArr[10][20];
+// CHECK-DAG: @"?FunArr@@3PAY0BE@P6AHHH@ZA"
+// X64-DAG: @"?FunArr@@3PAY0BE@P6AHHH@ZA"
+
+int (__stdcall *j)(signed char, unsigned char);
+// CHECK-DAG: @"?j@@3P6GHCE@ZA"
+
+const volatile char foo2::*k;
+// CHECK-DAG: @"?k@@3PTfoo@@DT1@"
+// X64-DAG: @"?k@@3PETfoo@@DET1@"
+
+int (foo2::*l)(int);
+// CHECK-DAG: @"?l@@3P8foo@@AEHH@ZQ1@"
+
+// Ensure typedef CV qualifiers are mangled correctly
+typedef const int cInt;
+typedef volatile int vInt;
+typedef const volatile int cvInt;
+
+extern cInt g_cInt = 1;
+vInt g_vInt = 2;
+cvInt g_cvInt = 3;
+
+// CHECK-DAG: @"?g_cInt@@3HB"
+// CHECK-DAG: @"?g_vInt@@3HC"
+// CHECK-DAG: @"?g_cvInt@@3HD"
+
+// Static functions are mangled, too.
+// Also make sure calling conventions, arglists, and throw specs work.
+static void __stdcall alpha(float a, double b) throw() {}
+bool __fastcall beta(long long a, wchar_t b) throw(signed char, unsigned char) {
+// CHECK-DAG: @"?beta@@YI_N_J_W@Z"
+// X64-DAG: @"?beta@@YA_N_J_W@Z"
+ alpha(0.f, 0.0);
+ return false;
+}
+
+// CHECK-DAG: @"?alpha@@YGXMN@Z"
+// X64-DAG: @"?alpha@@YAXMN@Z"
+
+// Make sure tag-type mangling works.
+void gamma(class foo, struct bar, union baz, enum quux) {}
+// CHECK-DAG: @"?gamma@@YAXVfoo@@Ubar@@Tbaz@@W4quux@@@Z"
+// X64-DAG: @"?gamma@@YAXVfoo@@Ubar@@Tbaz@@W4quux@@@Z"
+
+// Make sure pointer/reference-type mangling works.
+void delta(int * const a, const long &) {}
+// CHECK-DAG: @"?delta@@YAXQAHABJ@Z"
+// X64-DAG: @"?delta@@YAXQEAHAEBJ@Z"
+
+// Array mangling.
+void epsilon(int a[][10][20]) {}
+// CHECK-DAG: @"?epsilon@@YAXQAY19BE@H@Z"
+// X64-DAG: @"?epsilon@@YAXQEAY19BE@H@Z"
+
+void zeta(int (*)(int, int)) {}
+// CHECK-DAG: @"?zeta@@YAXP6AHHH@Z@Z"
+// X64-DAG: @"?zeta@@YAXP6AHHH@Z@Z"
+
+// Blocks mangling (Clang extension). A block should be mangled slightly
+// differently from a similar function pointer.
+void eta(int (^)(int, int)) {}
+// CHECK-DAG: @"?eta@@YAXP_EAHHH@Z@Z"
+
+typedef int theta_arg(int,int);
+void theta(theta_arg^ block) {}
+// CHECK-DAG: @"?theta@@YAXP_EAHHH@Z@Z"
+
+void operator_new_delete() {
+ char *ptr = new char;
+// CHECK-DAG: @"??2@YAPAXI@Z"
+
+ delete ptr;
+// CHECK-DAG: @"??3@YAXPAX@Z"
+
+ char *array = new char[42];
+// CHECK-DAG: @"??_U@YAPAXI@Z"
+
+ delete [] array;
+// CHECK-DAG: @"??_V@YAXPAX@Z"
+}
+
+// PR13022
+void (redundant_parens)();
+void redundant_parens_use() { redundant_parens(); }
+// CHECK-DAG: @"?redundant_parens@@YAXXZ"
+// X64-DAG: @"?redundant_parens@@YAXXZ"
+
+// PR13047
+typedef double RGB[3];
+RGB color1;
+// CHECK-DAG: @"?color1@@3PANA"
+extern const RGB color2 = {};
+// CHECK-DAG: @"?color2@@3QBNB"
+extern RGB const color3[5] = {};
+// CHECK-DAG: @"?color3@@3QAY02$$CBNA"
+extern RGB const ((color4)[5]) = {};
+// CHECK-DAG: @"?color4@@3QAY02$$CBNA"
+
+struct B;
+volatile int B::* volatile memptr1;
+// X64-DAG: @"?memptr1@@3RESB@@HES1@"
+volatile int B::* memptr2;
+// X64-DAG: @"?memptr2@@3PESB@@HES1@"
+int B::* volatile memptr3;
+// X64-DAG: @"?memptr3@@3REQB@@HEQ1@"
+typedef int (*fun)();
+volatile fun B::* volatile funmemptr1;
+// X64-DAG: @"?funmemptr1@@3RESB@@R6AHXZES1@"
+volatile fun B::* funmemptr2;
+// X64-DAG: @"?funmemptr2@@3PESB@@R6AHXZES1@"
+fun B::* volatile funmemptr3;
+// X64-DAG: @"?funmemptr3@@3REQB@@P6AHXZEQ1@"
+void (B::* volatile memptrtofun1)();
+// X64-DAG: @"?memptrtofun1@@3R8B@@EAAXXZEQ1@"
+const void (B::* memptrtofun2)();
+// X64-DAG: @"?memptrtofun2@@3P8B@@EAAXXZEQ1@"
+volatile void (B::* memptrtofun3)();
+// X64-DAG: @"?memptrtofun3@@3P8B@@EAAXXZEQ1@"
+int (B::* volatile memptrtofun4)();
+// X64-DAG: @"?memptrtofun4@@3R8B@@EAAHXZEQ1@"
+volatile int (B::* memptrtofun5)();
+// X64-DAG: @"?memptrtofun5@@3P8B@@EAA?CHXZEQ1@"
+const int (B::* memptrtofun6)();
+// X64-DAG: @"?memptrtofun6@@3P8B@@EAA?BHXZEQ1@"
+fun (B::* volatile memptrtofun7)();
+// X64-DAG: @"?memptrtofun7@@3R8B@@EAAP6AHXZXZEQ1@"
+volatile fun (B::* memptrtofun8)();
+// X64-DAG: @"?memptrtofun8@@3P8B@@EAAR6AHXZXZEQ1@"
+const fun (B::* memptrtofun9)();
+// X64-DAG: @"?memptrtofun9@@3P8B@@EAAQ6AHXZXZEQ1@"
+
+// PR12603
+enum E {};
+// CHECK-DAG: "?fooE@@YA?AW4E@@XZ"
+// X64-DAG: "?fooE@@YA?AW4E@@XZ"
+E fooE() { return E(); }
+
+class X {};
+// CHECK-DAG: "?fooX@@YA?AVX@@XZ"
+// X64-DAG: "?fooX@@YA?AVX@@XZ"
+X fooX() { return X(); }
+
+namespace PR13182 {
+ extern char s0[];
+ // CHECK-DAG: @"?s0@PR13182@@3PADA"
+ extern char s1[42];
+ // CHECK-DAG: @"?s1@PR13182@@3PADA"
+ extern const char s2[];
+ // CHECK-DAG: @"?s2@PR13182@@3QBDB"
+ extern const char s3[42];
+ // CHECK-DAG: @"?s3@PR13182@@3QBDB"
+ extern volatile char s4[];
+ // CHECK-DAG: @"?s4@PR13182@@3RCDC"
+ extern const volatile char s5[];
+ // CHECK-DAG: @"?s5@PR13182@@3SDDD"
+ extern const char* const* s6;
+ // CHECK-DAG: @"?s6@PR13182@@3PBQBDB"
+
+ char foo() {
+ return s0[0] + s1[0] + s2[0] + s3[0] + s4[0] + s5[0] + s6[0][0];
+ }
+}
+
+extern "C" inline void extern_c_func() {
+ static int local;
+// CHECK-DAG: @"?local@?1??extern_c_func@@9@4HA"
+// X64-DAG: @"?local@?1??extern_c_func@@9@4HA"
+}
+
+void call_extern_c_func() {
+ extern_c_func();
+}
+
+int main() { return 0; }
+// CHECK-DAG: @main
+// X64-DAG: @main
+
+int wmain() { return 0; }
+// CHECK-DAG: @wmain
+// X64-DAG: @wmain
+
+int WinMain() { return 0; }
+// CHECK-DAG: @WinMain
+// X64-DAG: @WinMain
+
+int wWinMain() { return 0; }
+// CHECK-DAG: @wWinMain
+// X64-DAG: @wWinMain
+
+int DllMain() { return 0; }
+// CHECK-DAG: @DllMain
+// X64-DAG: @DllMain
+
+inline int inline_function_with_local_type() {
+ static struct {
+ int a_field;
+ } static_variable_in_inline_function = { 20 }, second_static = { 40 };
+ // CHECK: @"?static_variable_in_inline_function@?1??inline_function_with_local_type@@YAHXZ@4U<unnamed-type-static_variable_in_inline_function>@?1??1@YAHXZ@A"
+
+ return static_variable_in_inline_function.a_field + second_static.a_field;
+}
+
+int call_inline_function_with_local_type() {
+ return inline_function_with_local_type();
+}
+
+template <typename T>
+inline int templated_inline_function_with_local_type() {
+ static struct {
+ int a_field;
+ } static_variable_in_templated_inline_function = { 20 },
+ second_static = { 40 };
+ // CHECK: @"?static_variable_in_templated_inline_function@?1???$templated_inline_function_with_local_type@H@@YAHXZ@4U<unnamed-type-static_variable_in_templated_inline_function>@?1???$templated_inline_function_with_local_type@H@@YAHXZ@A"
+
+ return static_variable_in_templated_inline_function.a_field +
+ second_static.a_field;
+}
+
+int call_templated_inline_function_with_local_type() {
+ return templated_inline_function_with_local_type<int>();
+}
+
+// PR17371
+struct OverloadedNewDelete {
+ // __cdecl
+ void *operator new(__SIZE_TYPE__);
+ void *operator new[](__SIZE_TYPE__);
+ void operator delete(void *);
+ void operator delete[](void *);
+ // __thiscall
+ int operator+(int);
+};
+
+void *OverloadedNewDelete::operator new(__SIZE_TYPE__ s) { return 0; }
+void *OverloadedNewDelete::operator new[](__SIZE_TYPE__ s) { return 0; }
+void OverloadedNewDelete::operator delete(void *) { }
+void OverloadedNewDelete::operator delete[](void *) { }
+int OverloadedNewDelete::operator+(int x) { return x; };
+
+// CHECK-DAG: ??2OverloadedNewDelete@@SAPAXI@Z
+// CHECK-DAG: ??_UOverloadedNewDelete@@SAPAXI@Z
+// CHECK-DAG: ??3OverloadedNewDelete@@SAXPAX@Z
+// CHECK-DAG: ??_VOverloadedNewDelete@@SAXPAX@Z
+// CHECK-DAG: ??HOverloadedNewDelete@@QAEHH@Z
+
+// X64-DAG: ??2OverloadedNewDelete@@SAPEAX_K@Z
+// X64-DAG: ??_UOverloadedNewDelete@@SAPEAX_K@Z
+// X64-DAG: ??3OverloadedNewDelete@@SAXPEAX@Z
+// X64-DAG: ??_VOverloadedNewDelete@@SAXPEAX@Z
+// X64-DAG: ??HOverloadedNewDelete@@QEAAHH@Z
+
+// Indirecting the function type through a typedef will require a calling
+// convention adjustment before building the method decl.
+
+typedef void *__thiscall OperatorNewType(__SIZE_TYPE__);
+typedef void __thiscall OperatorDeleteType(void *);
+
+struct TypedefNewDelete {
+ OperatorNewType operator new;
+ OperatorNewType operator new[];
+ OperatorDeleteType operator delete;
+ OperatorDeleteType operator delete[];
+};
+
+void *TypedefNewDelete::operator new(__SIZE_TYPE__ s) { return 0; }
+void *TypedefNewDelete::operator new[](__SIZE_TYPE__ s) { return 0; }
+void TypedefNewDelete::operator delete(void *) { }
+void TypedefNewDelete::operator delete[](void *) { }
+
+// CHECK-DAG: ??2TypedefNewDelete@@SAPAXI@Z
+// CHECK-DAG: ??_UTypedefNewDelete@@SAPAXI@Z
+// CHECK-DAG: ??3TypedefNewDelete@@SAXPAX@Z
+// CHECK-DAG: ??_VTypedefNewDelete@@SAXPAX@Z
+
+void __vectorcall vector_func() { }
+// CHECK-DAG: @"?vector_func@@YQXXZ"
+
+template <void (*)(void)>
+void fn_tmpl() {}
+
+template void fn_tmpl<extern_c_func>();
+// CHECK-DAG: @"??$fn_tmpl@$1?extern_c_func@@YAXXZ@@YAXXZ"
+
+extern "C" void __attribute__((overloadable)) overloaded_fn() {}
+// CHECK-DAG: @"?overloaded_fn@@$$J0YAXXZ"
+
+extern "C" void overloaded_fn2() {}
+// CHECK-DAG: @overloaded_fn2
+//
+extern "C" void __attribute__((overloadable)) overloaded_fn3();
+extern "C" void overloaded_fn3() {}
+// CHECK-DAG: @overloaded_fn3
+
+namespace UnnamedType {
+struct S {
+ typedef struct {} *T1[1];
+ typedef struct {} T2;
+ typedef struct {} *T3, T4;
+ using T5 = struct {};
+ using T6 = struct {} *;
+};
+void f(S::T1) {}
+void f(S::T2) {}
+void f(S::T3) {}
+void f(S::T4) {}
+void f(S::T5) {}
+void f(S::T6) {}
+// CHECK-DAG: @"?f@UnnamedType@@YAXQAPAU<unnamed-type-T1>@S@1@@Z"
+// CHECK-DAG: @"?f@UnnamedType@@YAXUT2@S@1@@Z"
+// CHECK-DAG: @"?f@UnnamedType@@YAXPAUT4@S@1@@Z"
+// CHECK-DAG: @"?f@UnnamedType@@YAXUT4@S@1@@Z"
+// CHECK-DAG: @"?f@UnnamedType@@YAXUT5@S@1@@Z"
+// CHECK-DAG: @"?f@UnnamedType@@YAXPAU<unnamed-type-T6>@S@1@@Z"
+
+// X64-DAG: @"?f@UnnamedType@@YAXQEAPEAU<unnamed-type-T1>@S@1@@Z"
+// X64-DAG: @"?f@UnnamedType@@YAXUT2@S@1@@Z"
+// X64-DAG: @"?f@UnnamedType@@YAXPEAUT4@S@1@@Z"(%"struct.UnnamedType::S::T4"
+// X64-DAG: @"?f@UnnamedType@@YAXUT4@S@1@@Z"
+// X64-DAG: @"?f@UnnamedType@@YAXUT5@S@1@@Z"
+// X64-DAG: @"?f@UnnamedType@@YAXPEAU<unnamed-type-T6>@S@1@@Z"
+}
+
+namespace PassObjectSize {
+// NOTE: This mangling is subject to change.
+// Reiterating from the comment in MicrosoftMangle, the scheme is pretend a
+// parameter of type __clang::__pass_object_sizeN exists after each pass object
+// size param P, where N is the Type of the pass_object_size attribute on P.
+//
+// e.g. we want to mangle:
+// void foo(void *const __attribute__((pass_object_size(0))));
+// as if it were
+// namespace __clang { enum __pass_object_size0 : size_t {}; }
+// void foo(void *const, __clang::__pass_object_size0);
+// where __clang is a top-level namespace.
+
+// CHECK-DAG: define dso_local i32 @"?foo@PassObjectSize@@YAHQAHW4__pass_object_size0@__clang@@@Z"
+int foo(int *const i __attribute__((pass_object_size(0)))) { return 0; }
+// CHECK-DAG: define dso_local i32 @"?bar@PassObjectSize@@YAHQAHW4__pass_object_size1@__clang@@@Z"
+int bar(int *const i __attribute__((pass_object_size(1)))) { return 0; }
+// CHECK-DAG: define dso_local i32 @"?qux@PassObjectSize@@YAHQAHW4__pass_object_size1@__clang@@0W4__pass_object_size0@3@@Z"
+int qux(int *const i __attribute__((pass_object_size(1))), int *const j __attribute__((pass_object_size(0)))) { return 0; }
+// CHECK-DAG: define dso_local i32 @"?zot@PassObjectSize@@YAHQAHW4__pass_object_size1@__clang@@01@Z"
+int zot(int *const i __attribute__((pass_object_size(1))), int *const j __attribute__((pass_object_size(1)))) { return 0; }
+}
+
+namespace Atomic {
+// CHECK-DAG: define dso_local void @"?f@Atomic@@YAXU?$_Atomic@H@__clang@@@Z"(
+void f(_Atomic(int)) {}
+}
+namespace Complex {
+// CHECK-DAG: define dso_local void @"?f@Complex@@YAXU?$_Complex@H@__clang@@@Z"(
+void f(_Complex int) {}
+}
+#ifdef ARM
+namespace Float16 {
+// ARM-DAG: define dso_local void @"?f@Float16@@YAXU_Float16@__clang@@@Z"(
+void f(_Float16) {}
+}
+#endif // ARM
+
+namespace PR26029 {
+template <class>
+struct L {
+ L() {}
+};
+template <class>
+class H;
+struct M : L<H<int *> > {};
+
+template <class>
+struct H {};
+
+template <class GT>
+void m_fn3() {
+ (H<GT *>());
+ M();
+}
+
+void runOnFunction() {
+ L<H<int *> > b;
+ m_fn3<int>();
+}
+// CHECK-DAG: call {{.*}} @"??0?$L@V?$H@PAH@PR26029@@@PR26029@@QAE@XZ"
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-neon-vectors.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-neon-vectors.cpp
new file mode 100644
index 0000000..6faf622
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-neon-vectors.cpp
@@ -0,0 +1,74 @@
+// RUN: %clang_cc1 -triple armv7-apple-ios -target-feature +neon %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-apple-ios -target-feature +neon %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-linux-gnu -target-feature +neon %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-AARCH64
+
+typedef float float32_t;
+typedef double float64_t;
+typedef __fp16 float16_t;
+#if defined(__aarch64__)
+typedef unsigned char poly8_t;
+typedef unsigned short poly16_t;
+#else
+typedef signed char poly8_t;
+typedef short poly16_t;
+#endif
+typedef unsigned __INT64_TYPE__ 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_vector_type(4))) float16_t float16x4_t;
+typedef __attribute__((neon_vector_type(8))) float16_t float16x8_t;
+#ifdef __aarch64__
+typedef __attribute__((neon_vector_type(2))) float64_t float64x2_t;
+#endif
+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
+// CHECK-AARCH64: 11__Int32x2_t
+void f1(int32x2_t v) { }
+
+// CHECK: 17__simd128_int32_t
+// CHECK-AARCH64: 11__Int32x4_t
+void f2(int32x4_t v) { }
+
+// CHECK: 17__simd64_uint64_t
+// CHECK-AARCH64: 12__Uint64x1_t
+void f3(uint64x1_t v) { }
+
+// CHECK: 18__simd128_uint64_t
+// CHECK-AARCH64: 12__Uint64x2_t
+void f4(uint64x2_t v) { }
+
+// CHECK: 18__simd64_float32_t
+// CHECK-AARCH64: 13__Float32x2_t
+void f5(float32x2_t v) { }
+
+// CHECK: 19__simd128_float32_t
+// CHECK-AARCH64: 13__Float32x4_t
+void f6(float32x4_t v) { }
+
+// CHECK: 18__simd64_float16_t
+// CHECK-AARCH64: 13__Float16x4_t
+void f7(float16x4_t v) {}
+
+// CHECK: 19__simd128_float16_t
+// CHECK-AARCH64: 13__Float16x8_t
+void f8(float16x8_t v) {}
+
+// CHECK: 17__simd128_poly8_t
+// CHECK-AARCH64: 12__Poly8x16_t
+void f9(poly8x16_t v) {}
+
+// CHECK: 18__simd128_poly16_t
+// CHECK-AARCH64: 12__Poly16x8_t
+void f10(poly16x8_t v) {}
+
+#ifdef __aarch64__
+// CHECK-AARCH64: 13__Float64x2_t
+void f11(float64x2_t v) { }
+#endif
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-nullptr-arg.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-nullptr-arg.cpp
new file mode 100644
index 0000000..e4ae353
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-nullptr-arg.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
+
+template<int *ip> struct IP {};
+
+// CHECK-LABEL: define {{.*}}void @_Z5test12IPILPi0EE
+void test1(IP<nullptr>) {}
+
+struct X{ };
+template<int X::*pm> struct PM {};
+
+// CHECK-LABEL: define {{.*}}void @_Z5test22PMILM1Xi0EE
+void test2(PM<nullptr>) { }
+
+// CHECK-LABEL: define {{.*}}void @_Z5test316DependentTypePtrIPiLS0_0EE
+template<typename T, T x> struct DependentTypePtr {};
+void test3(DependentTypePtr<int*,nullptr>) { }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-ref-qualifiers.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-ref-qualifiers.cpp
new file mode 100644
index 0000000..4552c93
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-ref-qualifiers.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
+struct X {
+ int f() &;
+ int g() &&;
+ int h() const &&;
+};
+
+// CHECK-LABEL: define i32 @_ZNR1X1fEv
+int X::f() & { return 0; }
+// CHECK-LABEL: define i32 @_ZNO1X1gEv
+int X::g() && { return 0; }
+// CHECK-LABEL: define i32 @_ZNKO1X1hEv
+int X::h() const && { return 0; }
+
+// CHECK-LABEL: define void @_Z1fM1XFivREMS_FivOEMS_KFivOE
+void f(int (X::*)() &, int (X::*)() &&, int (X::*)() const&&) { }
+
+// CHECK-LABEL: define void @_Z1g1AIFivEES_IFivREES_IFivOEES_IKFivEES_IKFivREES_IKFivOEES_IVKFivEES_IVKFivREES_IVKFivOEE()
+template <class T> struct A {};
+void g(A<int()>, A<int()&>, A<int()&&>,
+ A<int() const>, A<int() const &>, A<int() const &&>,
+ A<int() const volatile>, A<int() const volatile &>, A<int() const volatile &&>) {}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-std-externc.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-std-externc.cpp
new file mode 100644
index 0000000..f0c7d69
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-std-externc.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 %s -DNS=std -emit-llvm -triple %itanium_abi_triple -o - | FileCheck %s --check-prefix=CHECK-STD
+// RUN: %clang_cc1 %s -DNS=n -emit-llvm -triple %itanium_abi_triple -o - | FileCheck %s --check-prefix=CHECK-N
+
+// _ZNSt1DISt1CE1iE = std::D<std::C>::i
+// CHECK-STD: @_ZNSt1DISt1CE1iE =
+
+// _ZN1n1DINS_1CEE1iE == n::D<n::C>::i
+// CHECK-N: @_ZN1n1DINS_1CEE1iE =
+
+namespace NS {
+ extern "C" {
+ class C {
+ };
+ }
+
+ template <class T>
+ class D {
+ public:
+ static int i;
+ };
+
+}
+
+
+int f() {
+ return NS::D<NS::C>::i;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-subst-std.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-subst-std.cpp
new file mode 100644
index 0000000..b06f798
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-subst-std.cpp
@@ -0,0 +1,113 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s
+
+// Check mangling of Vtables, VTTs, and construction vtables that
+// involve standard substitutions.
+
+
+// CHECK: @_ZTVSd = linkonce_odr unnamed_addr constant
+// CHECK: @_ZTTSd = linkonce_odr unnamed_addr constant
+// CHECK: @_ZTCSd0_Si = linkonce_odr unnamed_addr constant
+// CHECK: @_ZTCSd16_So = linkonce_odr unnamed_addr constant
+// CHECK: @_ZTVSi = linkonce_odr unnamed_addr constant
+// CHECK: @_ZTTSi = linkonce_odr unnamed_addr constant
+// CHECK: @_ZTVSo = linkonce_odr unnamed_addr constant
+// CHECK: @_ZTTSo = linkonce_odr unnamed_addr constant
+
+namespace std {
+ struct A { A(); };
+
+ // CHECK-LABEL: define void @_ZNSt1AC2Ev(%"struct.std::A"* %this) unnamed_addr
+ // CHECK-LABEL: define void @_ZNSt1AC1Ev(%"struct.std::A"* %this) unnamed_addr
+ A::A() { }
+};
+
+namespace std {
+ template<typename> struct allocator { };
+}
+
+// CHECK-LABEL: define void @_Z1fSaIcESaIiE
+void f(std::allocator<char>, std::allocator<int>) { }
+
+namespace std {
+ template<typename, typename, typename> struct basic_string { };
+}
+
+// CHECK-LABEL: define void @_Z1fSbIcciE
+void f(std::basic_string<char, char, int>) { }
+
+namespace std {
+ template<typename> struct char_traits { };
+
+ typedef std::basic_string<char, std::char_traits<char>, std::allocator<char> > string;
+}
+
+// CHECK: _Z1fSs
+void f(std::string) { }
+
+namespace std {
+ template<typename, typename> struct basic_ios {
+ basic_ios(int);
+ virtual ~basic_ios();
+ };
+ template<typename charT, typename traits = char_traits<charT> >
+ struct basic_istream : virtual public basic_ios<charT, traits> {
+ basic_istream(int x) : basic_ios<charT, traits>(x), stored(x) { }
+
+ int stored;
+ };
+ template<typename charT, typename traits = char_traits<charT> >
+ struct basic_ostream : virtual public basic_ios<charT, traits> {
+ basic_ostream(int x) : basic_ios<charT, traits>(x), stored(x) { }
+
+ float stored;
+ };
+
+ template<typename charT, typename traits = char_traits<charT> >
+ struct basic_iostream : public basic_istream<charT, traits>,
+ public basic_ostream<charT, traits> {
+ basic_iostream(int x) : basic_istream<charT, traits>(x),
+ basic_ostream<charT, traits>(x),
+ basic_ios<charT, traits>(x) { }
+ };
+}
+
+// CHECK: _Z1fSi
+void f(std::basic_istream<char, std::char_traits<char> >) { }
+
+// CHECK: _Z1fSo
+void f(std::basic_ostream<char, std::char_traits<char> >) { }
+
+// CHECK: _Z1fSd
+void f(std::basic_iostream<char, std::char_traits<char> >) { }
+
+extern "C++" {
+namespace std
+{
+ typedef void (*terminate_handler) ();
+
+ // CHECK: _ZSt13set_terminatePFvvE
+ terminate_handler set_terminate(terminate_handler) { return 0; }
+}
+}
+
+// Make sure we don't treat the following like std::string
+// CHECK-LABEL: define void @_Z1f12basic_stringIcSt11char_traitsIcESaIcEE
+template<typename, typename, typename> struct basic_string { };
+typedef basic_string<char, std::char_traits<char>, std::allocator<char> > not_string;
+void f(not_string) { }
+
+// Manglings for instantiations caused by this function are at the
+// top of the test.
+void create_streams() {
+ std::basic_iostream<char> bio(17);
+}
+
+// Make sure we don't mangle 'std' as 'St' here.
+namespace N {
+ namespace std {
+ struct A { void f(); };
+
+ // CHECK-LABEL: define void @_ZN1N3std1A1fEv
+ void A::f() { }
+ }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-subst.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-subst.cpp
new file mode 100644
index 0000000..09326e2
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-subst.cpp
@@ -0,0 +1,98 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s
+
+struct X {};
+
+// CHECK-LABEL: define void @_Z1f1XS_(
+void f(X, X) { }
+
+// CHECK-LABEL: define void @_Z1fR1XS0_(
+void f(X&, X&) { }
+
+// CHECK-LABEL: define void @_Z1fRK1XS1_(
+void f(const X&, const X&) { }
+
+typedef void T();
+struct S {};
+
+// CHECK-LABEL: define void @_Z1fPFvvEM1SFvvE(
+void f(T*, T (S::*)) {}
+
+namespace A {
+ struct A { };
+ struct B { };
+};
+
+// CHECK-LABEL: define void @_Z1fN1A1AENS_1BE(
+void f(A::A a, A::B b) { }
+
+struct C {
+ struct D { };
+};
+
+// CHECK-LABEL: define void @_Z1fN1C1DERS_PS_S1_(
+void f(C::D, C&, C*, C&) { }
+
+template<typename T>
+struct V {
+ typedef int U;
+};
+
+template <typename T> void f1(typename V<T>::U, V<T>) { }
+
+// CHECK: @_Z2f1IiEvN1VIT_E1UES2_
+template void f1<int>(int, V<int>);
+
+template <typename T> void f2(V<T>, typename V<T>::U) { }
+
+// CHECK: @_Z2f2IiEv1VIT_ENS2_1UE
+template void f2<int>(V<int>, int);
+
+namespace NS {
+template <typename T> struct S1 {};
+template<typename T> void ft3(S1<T>, S1<char>) { }
+
+// CHECK: @_ZN2NS3ft3IiEEvNS_2S1IT_EENS1_IcEE
+template void ft3<int>(S1<int>, S1<char>);
+}
+
+// PR5196
+// CHECK: @_Z1fPKcS0_
+void f(const char*, const char*) {}
+
+namespace NS {
+ class C;
+}
+
+namespace NS {
+ // CHECK: @_ZN2NS1fERNS_1CE
+ void f(C&) { }
+}
+
+namespace Test1 {
+
+struct A { };
+struct B { };
+
+// CHECK: @_ZN5Test11fEMNS_1BEFvvENS_1AES3_
+void f(void (B::*)(), A, A) { }
+
+// CHECK: @_ZN5Test11fEMNS_1BEFvvENS_1AES3_MS0_FvS3_EMS3_FvvE
+void f(void (B::*)(), A, A, void (B::*)(A), void (A::*)()) { }
+
+}
+
+namespace ManglePrefix {
+template <typename>
+struct X {
+ template <typename>
+ struct Y {
+ typedef int type;
+ typedef int type2;
+ };
+};
+template <typename T>
+typename X<T>::template Y<T>::type f(typename X<T>::template Y<T>::type2) { return 0; }
+
+// CHECK: @_ZN12ManglePrefix1fIiEENS_1XIT_E1YIS2_E4typeENS5_5type2E
+template int f<int>(int);
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-system-header.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-system-header.cpp
new file mode 100644
index 0000000..3ab5f96
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-system-header.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s
+
+// PR5420
+
+# 1 "fake_system_header.h" 1 3 4
+// CHECK-LABEL: define void @_ZdlPvS_(
+void operator delete (void*, void*) {}
+
+// PR6217
+// CHECK-LABEL: define void @_Z3barv()
+void bar() { }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-template.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-template.cpp
new file mode 100644
index 0000000..2313469
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-template.cpp
@@ -0,0 +1,214 @@
+// RUN: %clang_cc1 -verify -Wno-return-type -Wno-main -std=c++11 -emit-llvm -triple %itanium_abi_triple -o - %s | FileCheck %s
+// expected-no-diagnostics
+
+namespace test1 {
+int x;
+template <int& D> class T { };
+// CHECK: void @_ZN5test12f0ENS_1TIL_ZNS_1xEEEE(
+void f0(T<x> a0) {}
+}
+
+namespace test1 {
+// CHECK: void @_ZN5test12f0Ef
+void f0(float) {}
+template<void (&)(float)> struct t1 {};
+// CHECK: void @_ZN5test12f1ENS_2t1IL_ZNS_2f0EfEEE(
+void f1(t1<f0> a0) {}
+}
+
+namespace test2 {
+// CHECK: void @_ZN5test22f0Ef
+void f0(float) {}
+template<void (*)(float)> struct t1 {};
+// CHECK: void @_ZN5test22f1ENS_2t1IXadL_ZNS_2f0EfEEEE(
+void f1(t1<f0> a0) {}
+}
+
+namespace test3 {
+// CHECK: void @test3_f0
+extern "C" void test3_f0(float) {}
+template<void (&)(float)> struct t1 {};
+// CHECK: void @_ZN5test32f1ENS_2t1IL_Z8test3_f0EEE(
+void f1(t1<test3_f0> a0) {}
+}
+
+namespace test4 {
+// CHECK: void @test4_f0
+extern "C" void test4_f0(float) {}
+template<void (*)(float)> struct t1 {};
+// CHECK: void @_ZN5test42f1ENS_2t1IXadL_Z8test4_f0EEEE(
+void f1(t1<test4_f0> a0) {}
+}
+
+// CHECK: void @test5_f0
+extern "C" void test5_f0(float) {}
+int main(int) {}
+
+namespace test5 {
+template<void (&)(float)> struct t1 {};
+// CHECK: void @_ZN5test52f1ENS_2t1IL_Z8test5_f0EEE(
+void f1(t1<test5_f0> a0) {}
+
+template<int (&)(int)> struct t2 {};
+// CHECK: void @_ZN5test52f2ENS_2t2IL_Z4mainEEE
+void f2(t2<main> a0) {}
+}
+
+namespace test6 {
+struct A { void im0(float); };
+// CHECK: void @_ZN5test61A3im0Ef
+void A::im0(float) {}
+template <void(A::*)(float)> class T { };
+// CHECK: void @_ZN5test62f0ENS_1TIXadL_ZNS_1A3im0EfEEEE(
+void f0(T<&A::im0> a0) {}
+}
+
+namespace test7 {
+ template<typename T>
+ struct meta {
+ static const unsigned value = sizeof(T);
+ };
+
+ template<unsigned> struct int_c {
+ typedef float type;
+ };
+
+ template<typename T>
+ struct X {
+ template<typename U>
+ X(U*, typename int_c<(meta<T>::value + meta<U>::value)>::type *) { }
+ };
+
+ // CHECK: define weak_odr {{.*}} @_ZN5test71XIiEC1IdEEPT_PNS_5int_cIXplL_ZNS_4metaIiE5valueEEsr4metaIS3_EE5valueEE4typeE(
+ template X<int>::X(double*, float*);
+}
+
+namespace test8 {
+ template<typename T>
+ struct meta {
+ struct type {
+ static const unsigned value = sizeof(T);
+ };
+ };
+
+ template<unsigned> struct int_c {
+ typedef float type;
+ };
+
+ template<typename T>
+ void f(int_c<meta<T>::type::value>) { }
+
+ // CHECK-LABEL: define weak_odr {{.*}}void @_ZN5test81fIiEEvNS_5int_cIXsr4metaIT_E4typeE5valueEEE(
+ template void f<int>(int_c<sizeof(int)>);
+}
+
+namespace test9 {
+ template<typename T>
+ struct supermeta {
+ template<typename U>
+ struct apply {
+ typedef T U::*type;
+ };
+ };
+
+ struct X { };
+
+ template<typename T, typename U>
+ typename supermeta<T>::template apply<U>::type f();
+
+ void test_f() {
+ // CHECK: @_ZN5test91fIiNS_1XEEENS_9supermetaIT_E5applyIT0_E4typeEv()
+ // Note: GCC incorrectly mangles this as
+ // _ZN5test91fIiNS_1XEEENS_9supermetaIT_E5apply4typeEv, while EDG
+ // gets it right.
+ f<int, X>();
+ }
+}
+
+namespace test10 {
+ template<typename T>
+ struct X {
+ template<typename U>
+ struct definition {
+ };
+ };
+
+ // CHECK: _ZN6test101fIidEENS_1XIT_E10definitionIT0_EES2_S5_
+ template<typename T, typename U>
+ typename X<T>::template definition<U> f(T, U) { }
+
+ void g(int i, double d) {
+ f(i, d);
+ }
+}
+
+// Report from cxx-abi-dev, 2012.01.04.
+namespace test11 {
+ int cmp(char a, char b);
+ template <typename T, int (*cmp)(T, T)> struct A {};
+ template <typename T> void f(A<T,cmp> &) {}
+ template void f<char>(A<char,cmp> &);
+ // CHECK: @_ZN6test111fIcEEvRNS_1AIT_L_ZNS_3cmpEccEEE(
+}
+
+namespace test12 {
+ // Make sure we can mangle non-type template args with internal linkage.
+ static int f() {}
+ const int n = 10;
+ template<typename T, T v> void test() {}
+ void use() {
+ // CHECK-LABEL: define internal {{.*}}void @_ZN6test124testIFivEXadL_ZNS_L1fEvEEEEvv(
+ test<int(), &f>();
+ // CHECK-LABEL: define internal {{.*}}void @_ZN6test124testIRFivEL_ZNS_L1fEvEEEvv(
+ test<int(&)(), f>();
+ // CHECK-LABEL: define internal {{.*}}void @_ZN6test124testIPKiXadL_ZNS_L1nEEEEEvv(
+ test<const int*, &n>();
+ // CHECK-LABEL: define internal {{.*}}void @_ZN6test124testIRKiL_ZNS_L1nEEEEvv(
+ test<const int&, n>();
+ }
+}
+
+// rdar://problem/12072531
+// Test the boundary condition of minimal signed integers.
+namespace test13 {
+ template <char c> char returnChar() { return c; }
+ template char returnChar<-128>();
+ // CHECK: @_ZN6test1310returnCharILcn128EEEcv()
+
+ template <short s> short returnShort() { return s; }
+ template short returnShort<-32768>();
+ // CHECK: @_ZN6test1311returnShortILsn32768EEEsv()
+}
+
+namespace test14 {
+ template <typename> inline int inl(bool b) {
+ if (b) {
+ static struct {
+ int field;
+ } a;
+ // CHECK: @_ZZN6test143inlIvEEibE1a
+
+ return a.field;
+ } else {
+ static struct {
+ int field;
+ } a;
+ // CHECK: @_ZZN6test143inlIvEEibE1a_0
+
+ return a.field;
+ }
+ }
+
+ int call(bool b) { return inl<void>(b); }
+}
+
+namespace std {
+template <class _Tp, _Tp...> struct integer_sequence {};
+}
+
+namespace test15 {
+template <int N>
+__make_integer_seq<std::integer_sequence, int, N> make() {}
+template __make_integer_seq<std::integer_sequence, int, 5> make<5>();
+// CHECK: define weak_odr {{.*}} @_ZN6test154makeILi5EEE18__make_integer_seqISt16integer_sequenceiXT_EEv(
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-this-cxx11.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-this-cxx11.cpp
new file mode 100644
index 0000000..f9e9479
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-this-cxx11.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s
+
+struct B {
+ template <class U> U f();
+};
+
+struct A {
+ B b;
+ // implicitly rewritten to (*this).b.f<U>()
+ template <class U> auto f() -> decltype (b.f<U>());
+ template <class U> auto g() -> decltype (this->b.f<U>());
+};
+
+int main() {
+ A a;
+ // CHECK: call i32 @_ZN1A1fIiEEDTcldtdtdefpT1b1fIT_EEEv
+ a.f<int>();
+ // CHECK: call i32 @_ZN1A1gIiEEDTcldtptfpT1b1fIT_EEEv
+ a.g<int>();
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-unnameable-conversions.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-unnameable-conversions.cpp
new file mode 100644
index 0000000..2ecded0
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-unnameable-conversions.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
+
+template<typename T> using id = T;
+struct S {
+ template<typename T, int N>
+ operator id<T[N]>&();
+ template<typename T, typename U>
+ operator id<T (U::*)()>() const;
+};
+
+void f() {
+ int (&a)[42] = S(); // CHECK: @_ZN1ScvRAT0__T_IiLi42EEEv(
+ char (S::*fp)() = S(); // CHECK: @_ZNK1ScvMT0_FT_vEIcS_EEv(
+};
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-unnamed.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-unnamed.cpp
new file mode 100644
index 0000000..c90f47b
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-unnamed.cpp
@@ -0,0 +1,95 @@
+// RUN: %clang_cc1 -std=c++98 -emit-llvm %s -o - -triple=x86_64-apple-darwin10 | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=x86_64-apple-darwin10 | FileCheck %s
+
+struct S {
+ virtual ~S() { }
+};
+
+// PR5706
+// Make sure this doesn't crash; the mangling doesn't matter because the name
+// doesn't have linkage.
+static struct : S { } obj8;
+
+void f() {
+ // Make sure this doesn't crash; the mangling doesn't matter because the
+ // generated vtable/etc. aren't modifiable (although it would be nice for
+ // codesize to make it consistent inside inline functions).
+ static struct : S { } obj8;
+}
+
+inline int f2() {
+ // FIXME: We don't mangle the names of a or x correctly!
+ static struct { int a() { static int x; return ++x; } } obj;
+ return obj.a();
+}
+
+int f3() { return f2(); }
+
+struct A {
+ typedef struct { int x; } *ptr;
+ ptr m;
+ int a() {
+ static struct x {
+ // FIXME: We don't mangle the names of a or x correctly!
+ int a(ptr A::*memp) { static int x; return ++x; }
+ } a;
+ return a.a(&A::m);
+ }
+};
+
+int f4() { return A().a(); }
+
+int f5() {
+ static union {
+ int a;
+ };
+
+ // CHECK: _ZZ2f5vE1a
+ return a;
+}
+
+#if __cplusplus <= 199711L
+int f6() {
+ static union {
+ union {
+ int : 1;
+ };
+ int b;
+ };
+
+ // CXX98: _ZZ2f6vE1b
+ return b;
+}
+#endif
+
+int f7() {
+ static union {
+ union {
+ int b;
+ } a;
+ };
+
+ // 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-LABEL: define internal void @"_ZNV3$_35test9Ev"(
+typedef volatile struct {
+ void test9() volatile {}
+} Test9;
+void test9() {
+ Test9 a;
+ a.test9();
+}
+
+// CHECK-LABEL: define internal void @"_ZN5Test8I3$_2EC1ES0_"(
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-valist.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-valist.cpp
new file mode 100644
index 0000000..0fcc1db
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-valist.cpp
@@ -0,0 +1,44 @@
+#include "stdarg.h"
+
+namespace test1 {
+ void test1(const char *fmt, va_list ap) {
+ }
+}
+
+class Test2 {
+public:
+ void test2(const char *fmt, va_list ap);
+};
+
+void Test2::test2(const char *fmt, va_list ap) {
+}
+
+// RUN: %clang_cc1 %s -emit-llvm -o - \
+// RUN: -triple armv7-unknown-linux \
+// RUN: | FileCheck -check-prefix=CHECK-MANGLE-ARM-AAPCS %s
+// CHECK-MANGLE-ARM-AAPCS: @_ZN5test15test1EPKcSt9__va_list
+// CHECK-MANGLE-ARM-AAPCS: @_ZN5Test25test2EPKcSt9__va_list
+
+// RUN: %clang_cc1 %s -emit-llvm -o - \
+// RUN: -triple armv7-unknown-linux -target-abi apcs-gnu \
+// RUN: | FileCheck -check-prefix=CHECK-MANGLE-ARM-APCS %s
+// CHECK-MANGLE-ARM-APCS: @_ZN5test15test1EPKcPv
+// CHECK-MANGLE-ARM-APCS: @_ZN5Test25test2EPKcPv
+
+// RUN: %clang_cc1 %s -emit-llvm -o - \
+// RUN: -triple mipsel-unknown-linux \
+// RUN: | FileCheck -check-prefix=CHECK-MANGLE-MIPSEL %s
+// CHECK-MANGLE-MIPSEL: @_ZN5test15test1EPKcPv
+// CHECK-MANGLE-MIPSEL: @_ZN5Test25test2EPKcPv
+
+// RUN: %clang_cc1 %s -emit-llvm -o - \
+// RUN: -triple i686-unknown-linux \
+// RUN: | FileCheck -check-prefix=CHECK-MANGLE-X86 %s
+// CHECK-MANGLE-X86: @_ZN5test15test1EPKcPc
+// CHECK-MANGLE-X86: @_ZN5Test25test2EPKcPc
+
+// RUN: %clang_cc1 %s -emit-llvm -o - \
+// RUN: -triple x86_64-unknown-linux \
+// RUN: | FileCheck -check-prefix=CHECK-MANGLE-X86-64 %s
+// CHECK-MANGLE-X86-64: @_ZN5test15test1EPKcP13__va_list_tag
+// CHECK-MANGLE-X86-64: @_ZN5Test25test2EPKcP13__va_list_tag
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-variadic-templates.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-variadic-templates.cpp
new file mode 100644
index 0000000..d2c1b77
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-variadic-templates.cpp
@@ -0,0 +1,77 @@
+// RUN: %clang_cc1 -std=c++11 -emit-llvm -triple=x86_64-apple-darwin9 -o - %s | FileCheck %s
+
+template<unsigned I, typename ...Types>
+struct X { };
+
+template<typename T> struct identity { using type = T; };
+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 { };
+template<typename ...T> using ArrayOfN = int[sizeof...(T)];
+
+// CHECK-LABEL: define weak_odr void @_Z2f0IJEEv1XIXsZT_EJDpRT_EE
+template<typename ...Types>
+void f0(X<sizeof...(Types), Types&...>) { }
+
+template void f0(X<0>);
+
+// CHECK-LABEL: 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-LABEL: define weak_odr void @_Z2f1IJEEvv
+template void f1<>();
+// CHECK-LABEL: define weak_odr void @_Z2f1IJiEEvv
+template void f1<int>();
+// CHECK-LABEL: define weak_odr void @_Z2f1IJifEEvv
+template void f1<int, float>();
+
+// Mangling function parameter packs
+template<typename ...Types> void f2(Types...) {}
+// CHECK-LABEL: define weak_odr void @_Z2f2IJEEvDpT_
+template void f2<>();
+// CHECK-LABEL: define weak_odr void @_Z2f2IJiEEvDpT_
+template void f2<int>(int);
+// CHECK-LABEL: 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-LABEL: define weak_odr void @_Z2f3IJEEvDpPKT_
+template void f3<>();
+// CHECK-LABEL: define weak_odr void @_Z2f3IJiEEvDpPKT_
+template void f3<int>(const int*);
+// CHECK-LABEL: 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-LABEL: 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-LABEL: 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-LABEL: 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-LABEL: define weak_odr void @_Z2f7IJ8identity13add_referenceEE14template_tupleIJDpT_EEv
+template template_tuple<identity, add_reference> f7();
+
+template<typename T, typename ...U> void f8(ArrayOfN<int, U..., T, typename U::type...>&) {}
+// CHECK-LABEL: define weak_odr void @_Z2f8IiJ8identityIiES0_IfEEEvRAsPiDpT0_T_DpNS3_4typeEE_i
+template void f8<int, identity<int>, identity<float>>(int (&)[6]);
+
+template<typename ...T> void f10(ArrayOfN<T...> &) {}
+// FIXME: This is wrong; should be @_Z3f10IJifEEvRAsZT__i
+// CHECK-LABEL: define weak_odr void @_Z3f10IJifEEvRAsPDpT_E_i
+template void f10<int, float>(int (&)[2]);
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-win-ccs.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-win-ccs.cpp
new file mode 100644
index 0000000..f5ddf97
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-win-ccs.cpp
@@ -0,0 +1,70 @@
+// RUN: %clang_cc1 %s -emit-llvm -triple i686-windows-gnu -o - | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -triple i686-windows-itanium -o - | FileCheck %s
+
+// GCC 5.1 began mangling these Windows calling conventions into function
+// types, since they can be used for overloading. They've always been mangled
+// in the MS ABI, but they are new to the Itanium mangler. Note that the main
+// function definition does not use a calling convention. Only function types
+// that appear later use it.
+
+template <typename Fn> static int func_as_ptr(Fn fn) { return int(fn); }
+
+void f_cdecl(int, int);
+void __attribute__((stdcall)) f_stdcall(int, int);
+void __attribute__((fastcall)) f_fastcall(int, int);
+void __attribute__((thiscall)) f_thiscall(int, int);
+
+int as_cdecl() { return func_as_ptr(f_cdecl); }
+int as_stdcall() { return func_as_ptr(f_stdcall); }
+int as_fastcall() { return func_as_ptr(f_fastcall); }
+
+// CHECK: define dso_local i32 @_Z8as_cdeclv()
+// CHECK: call i32 @_ZL11func_as_ptrIPFviiEEiT_(void (i32, i32)* @_Z7f_cdeclii)
+
+// CHECK: define dso_local i32 @_Z10as_stdcallv()
+// CHECK: call i32 @_ZL11func_as_ptrIPU7stdcallFviiEEiT_(void (i32, i32)* @"\01__Z9f_stdcallii@8")
+
+// CHECK: define dso_local i32 @_Z11as_fastcallv()
+// CHECK: call i32 @_ZL11func_as_ptrIPU8fastcallFviiEEiT_(void (i32, i32)* @"\01@_Z10f_fastcallii@8")
+
+// PR40107: We should mangle thiscall here but we don't because we can't
+// disambiguate it from the member pointer case below where it shouldn't be
+// mangled.
+//int as_thiscall() { return func_as_ptr(f_thiscall); }
+// CHECKX: define dso_local i32 @_Z11as_thiscallv()
+// CHECKX: call i32 @_ZL11func_as_ptrIPU8thiscallFviiEEiT_(void (i32, i32)* @_Z10f_thiscallii)
+
+// CHECK: define dso_local void @_Z11funcRefTypeRU8fastcallFviiE(void (i32, i32)* %fr)
+void funcRefType(void(__attribute__((fastcall)) & fr)(int, int)) {
+ fr(1, 2);
+}
+
+struct Foo { void bar(int, int); };
+
+// PR40107: In this case, the member function pointer uses the thiscall
+// convention, but GCC doesn't mangle it, so we don't either.
+// CHECK: define dso_local void @_Z15memptr_thiscallP3FooMS_FvvE(%struct.Foo* {{.*}})
+void memptr_thiscall(Foo *o, void (Foo::*mp)()) { (o->*mp)(); }
+
+// CHECK: define dso_local void @_Z12memptrCCTypeR3FooMS_U8fastcallFviiE(%struct.Foo* {{.*}}, { i32, i32 }* byval{{.*}})
+void memptrCCType(Foo &o, void (__attribute__((fastcall)) Foo::*mp)(int, int)) {
+ (o.*mp)(1, 2);
+}
+
+// CHECK: define dso_local i32 @_Z17useTemplateFnTypev()
+// CHECK: call i32 @_ZL14templateFnTypeIU8fastcallFviiEElPT_(void (i32, i32)* @"\01@_Z10f_fastcallii@8")
+template <typename Fn> static long templateFnType(Fn *fn) { return long(fn); }
+long useTemplateFnType() { return templateFnType(f_fastcall); }
+
+// CHECK: define weak_odr dso_local x86_fastcallcc void @"\01@_Z10fnTemplateIsEvv@0"()
+// CHECK: define dso_local x86_fastcallcc void @"\01@_Z10fnTemplateIiEvv@0"()
+template <typename T> void __attribute__((fastcall)) fnTemplate() {}
+template void __attribute__((fastcall)) fnTemplate<short>();
+template <> void __attribute__((fastcall)) fnTemplate<int>() {}
+
+// CHECK: define weak_odr dso_local x86_fastcallcc void (i32, i32)* @"\01@_Z12fnTempReturnIsEPU8fastcallFviiEv@0"()
+// CHECK: define dso_local x86_fastcallcc void (i32, i32)* @"\01@_Z12fnTempReturnIiEPU8fastcallFviiEv@0"()
+typedef void (__attribute__((fastcall)) *fp_cc_t)(int, int);
+template <typename T> fp_cc_t __attribute__((fastcall)) fnTempReturn() { return nullptr; }
+template fp_cc_t __attribute__((fastcall)) fnTempReturn<short>();
+template <> fp_cc_t __attribute__((fastcall)) fnTempReturn<int>() { return nullptr; }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-win64-ccs.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-win64-ccs.cpp
new file mode 100644
index 0000000..10c0430
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-win64-ccs.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple x86_64-windows-gnu -o - -emit-llvm %s | FileCheck %s -check-prefix CHECK-WIN
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -o - -emit-llvm %s | FileCheck %s -check-prefix CHECK-LIN
+
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+template <typename FTy> ptrdiff_t func_as_int(FTy *fp) { return ptrdiff_t(fp); }
+
+int f_plain(int);
+int __attribute__((sysv_abi)) f_sysvabi(int);
+int __attribute__((ms_abi)) f_msabi(int);
+ptrdiff_t useThem() {
+ ptrdiff_t rv = 0;
+ rv += func_as_int(f_plain);
+ rv += func_as_int(f_sysvabi);
+ rv += func_as_int(f_msabi);
+ return rv;
+}
+
+// CHECK-WIN: define dso_local i64 @_Z7useThemv()
+// CHECK-WIN: call i64 @_Z11func_as_intIFiiEExPT_(i32 (i32)* @_Z7f_plaini)
+// CHECK-WIN: call i64 @_Z11func_as_intIU8sysv_abiFiiEExPT_(i32 (i32)* @_Z9f_sysvabii)
+// CHECK-WIN: call i64 @_Z11func_as_intIFiiEExPT_(i32 (i32)* @_Z7f_msabii)
+
+// CHECK-LIN: define i64 @_Z7useThemv()
+// CHECK-LIN: call i64 @_Z11func_as_intIFiiEElPT_(i32 (i32)* @_Z7f_plaini)
+// CHECK-LIN: call i64 @_Z11func_as_intIFiiEElPT_(i32 (i32)* @_Z9f_sysvabii)
+// CHECK-LIN: call i64 @_Z11func_as_intIU6ms_abiFiiEElPT_(i32 (i32)* @_Z7f_msabii)
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle-windows.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle-windows.cpp
new file mode 100644
index 0000000..a9d7be1
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle-windows.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 | \
+// RUN: FileCheck --check-prefix=WIN %s
+//
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-mingw32 | \
+// RUN: FileCheck --check-prefix=ITANIUM %s
+
+void __stdcall f1(void) {}
+// WIN: define dso_local x86_stdcallcc void @"?f1@@YGXXZ"
+// ITANIUM: define dso_local x86_stdcallcc void @"\01__Z2f1v@0"
+
+void __fastcall f2(void) {}
+// WIN: define dso_local x86_fastcallcc void @"?f2@@YIXXZ"
+// ITANIUM: define dso_local x86_fastcallcc void @"\01@_Z2f2v@0"
+
+extern "C" void __stdcall f3(void) {}
+// WIN: define dso_local x86_stdcallcc void @"\01_f3@0"
+// ITANIUM: define dso_local x86_stdcallcc void @"\01_f3@0"
+
+extern "C" void __fastcall f4(void) {}
+// WIN: define dso_local x86_fastcallcc void @"\01@f4@0"
+// ITANIUM: define dso_local x86_fastcallcc void @"\01@f4@0"
+
+struct Foo {
+ void __stdcall foo();
+ static void __stdcall bar();
+};
+
+void Foo::foo() {}
+// WIN: define dso_local x86_stdcallcc void @"?foo@Foo@@QAGXXZ"
+// ITANIUM: define dso_local x86_stdcallcc void @"\01__ZN3Foo3fooEv@4"
+
+void Foo::bar() {}
+// WIN: define dso_local x86_stdcallcc void @"?bar@Foo@@SGXXZ"
+// ITANIUM: define dso_local x86_stdcallcc void @"\01__ZN3Foo3barEv@0"
+
+// Mostly a test that we don't crash and that the names start with a \01.
+// gcc on mingw produces __Zpp@4
+// cl produces _++@4
+extern "C" void __stdcall operator++(Foo &x) {
+}
+// WIN: define dso_local x86_stdcallcc void @"??E@YGXAAUFoo@@@Z"
+// ITANIUM: define dso_local x86_stdcallcc void @"\01__ZppR3Foo@4"
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mangle.cpp b/src/llvm-project/clang/test/CodeGenCXX/mangle.cpp
new file mode 100644
index 0000000..919f8af
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mangle.cpp
@@ -0,0 +1,1140 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -fblocks -std=c++11 | FileCheck %s
+struct X { };
+struct Y { };
+
+// CHECK: @unmangled_variable = global
+// CHECK: @_ZN1N1iE = global
+// CHECK: @_ZZN1N1fEiiE1b = internal global
+// CHECK: @_ZZN1N1gEvE1a = internal global
+// CHECK: @_ZGVZN1N1gEvE1a = internal global
+
+//CHECK: @pr5966_i = external global
+//CHECK: @_ZL8pr5966_j = internal global
+
+// CHECK-LABEL: define zeroext i1 @_ZplRK1YRA100_P1X
+bool operator+(const Y&, X* (&xs)[100]) { return false; }
+
+// CHECK-LABEL: define void @_Z1f1s
+typedef struct { int a; } s;
+void f(s) { }
+
+// CHECK-LABEL: define void @_Z1f1e
+typedef enum { foo } e;
+void f(e) { }
+
+// CHECK-LABEL: define void @_Z1f1u
+typedef union { int a; } u;
+void f(u) { }
+
+// CHECK-LABEL: define void @_Z1f1x
+typedef struct { int a; } x,y;
+void f(y) { }
+
+// CHECK-LABEL: define void @_Z1fv
+void f() { }
+
+// CHECK-LABEL: define void @_ZN1N1fEv
+namespace N { void f() { } }
+
+// CHECK-LABEL: define void @_ZN1N1N1fEv
+namespace N { namespace N { void f() { } } }
+
+// CHECK-LABEL: define void @unmangled_function
+extern "C" { namespace N { void unmangled_function() { } } }
+
+extern "C" { namespace N { int unmangled_variable = 10; } }
+
+namespace N { int i; }
+
+namespace N { int f(int, int) { static int b; return b; } }
+
+namespace N { int h(); void g() { static int a = h(); } }
+
+// CHECK-LABEL: define void @_Z1fno
+void f(__int128_t, __uint128_t) { }
+
+template <typename T> struct S1 {};
+
+// CHECK-LABEL: define void @_Z1f2S1IiE
+void f(S1<int>) {}
+
+// CHECK-LABEL: define void @_Z1f2S1IdE
+void f(S1<double>) {}
+
+template <int N> struct S2 {};
+// CHECK-LABEL: define void @_Z1f2S2ILi100EE
+void f(S2<100>) {}
+
+// CHECK-LABEL: define void @_Z1f2S2ILin100EE
+void f(S2<-100>) {}
+
+template <bool B> struct S3 {};
+
+// CHECK-LABEL: define void @_Z1f2S3ILb1EE
+void f(S3<true>) {}
+
+// CHECK-LABEL: define void @_Z1f2S3ILb0EE
+void f(S3<false>) {}
+
+struct S;
+
+// CHECK-LABEL: define void @_Z1fM1SKFvvE
+void f(void (S::*)() const) {}
+
+// CHECK-LABEL: define void @_Z1fM1SFvvE
+void f(void (S::*)()) {}
+
+// CHECK-LABEL: define void @_Z1fi
+void f(const int) { }
+
+template<typename T, typename U> void ft1(U u, T t) { }
+
+template<typename T> void ft2(T t, void (*)(T), void (*)(T)) { }
+
+template<typename T, typename U = S1<T> > struct S4 { };
+template<typename T> void ft3(S4<T>*) { }
+
+namespace NS {
+ template<typename T> void ft1(T) { }
+}
+
+void g1() {
+ // CHECK: @_Z3ft1IidEvT0_T_
+ ft1<int, double>(1, 0);
+
+ // CHECK: @_Z3ft2IcEvT_PFvS0_ES2_
+ ft2<char>(1, 0, 0);
+
+ // CHECK: @_Z3ft3IiEvP2S4IT_2S1IS1_EE
+ ft3<int>(0);
+
+ // CHECK: @_ZN2NS3ft1IiEEvT_
+ NS::ft1<int>(1);
+}
+
+// Expressions
+template<int I> struct S5 { };
+
+template<int I> void ft4(S5<I>) { }
+void g2() {
+ // CHECK: @_Z3ft4ILi10EEv2S5IXT_EE
+ ft4(S5<10>());
+
+ // CHECK: @_Z3ft4ILi20EEv2S5IXT_EE
+ ft4(S5<20>());
+}
+
+extern "C++" {
+ // CHECK: @_Z1hv
+ void h() { }
+}
+
+// PR5019
+extern "C" { struct a { int b; }; }
+
+// CHECK: @_Z1fP1a
+int f(struct a *x) {
+ return x->b;
+}
+
+// PR5017
+extern "C" {
+struct Debug {
+ const Debug& operator<< (unsigned a) const { return *this; }
+};
+Debug dbg;
+// CHECK: @_ZNK5DebuglsEj
+int main(void) { dbg << 32 ;}
+}
+
+template<typename T> struct S6 {
+ typedef int B;
+};
+
+template<typename T> void ft5(typename S6<T>::B) { }
+// CHECK: @_Z3ft5IiEvN2S6IT_E1BE
+template void ft5<int>(int);
+
+template<typename T> class A {};
+
+namespace NS {
+template<typename T> bool operator==(const A<T>&, const A<T>&) { return true; }
+}
+
+// CHECK: @_ZN2NSeqIcEEbRK1AIT_ES5_
+template bool NS::operator==(const ::A<char>&, const ::A<char>&);
+
+namespace std {
+template<typename T> bool operator==(const A<T>&, const A<T>&) { return true; }
+}
+
+// CHECK: @_ZSteqIcEbRK1AIT_ES4_
+template bool std::operator==(const ::A<char>&, const ::A<char>&);
+
+struct S {
+ typedef int U;
+};
+
+template <typename T> typename T::U ft6(const T&) { return 0; }
+
+// CHECK: @_Z3ft6I1SENT_1UERKS1_
+template int ft6<S>(const S&);
+
+template<typename> struct __is_scalar_type {
+ enum { __value = 1 };
+};
+
+template<bool, typename> struct __enable_if { };
+
+template<typename T> struct __enable_if<true, T> {
+ typedef T __type;
+};
+
+// PR5063
+template<typename T> typename __enable_if<__is_scalar_type<T>::__value, void>::__type ft7() { }
+
+// CHECK: @_Z3ft7IiEN11__enable_ifIXsr16__is_scalar_typeIT_EE7__valueEvE6__typeEv
+template void ft7<int>();
+// CHECK: @_Z3ft7IPvEN11__enable_ifIXsr16__is_scalar_typeIT_EE7__valueEvE6__typeEv
+template void ft7<void*>();
+
+// PR5144
+extern "C" {
+void extern_f(void);
+};
+
+// CHECK: @extern_f
+void extern_f(void) { }
+
+struct S7 {
+ S7();
+
+ struct S { S(); };
+ struct {
+ S s;
+ } a;
+};
+
+// PR5139
+// CHECK: @_ZN2S7C2Ev
+// CHECK: @_ZN2S7Ut_C1Ev
+// CHECK: @_ZN2S7C1Ev
+S7::S7() {}
+
+// PR5063
+template<typename T> typename __enable_if<(__is_scalar_type<T>::__value), void>::__type ft8() { }
+// CHECK: @_Z3ft8IiEN11__enable_ifIXsr16__is_scalar_typeIT_EE7__valueEvE6__typeEv
+template void ft8<int>();
+// CHECK: @_Z3ft8IPvEN11__enable_ifIXsr16__is_scalar_typeIT_EE7__valueEvE6__typeEv
+template void ft8<void*>();
+
+// PR5796
+namespace PR5796 {
+template<typename> struct __is_scalar_type {
+ enum { __value = 0 };
+};
+
+template<bool, typename> struct __enable_if {};
+template<typename T> struct __enable_if<true, T> { typedef T __type; };
+template<typename T>
+
+// CHECK-LABEL: define linkonce_odr void @_ZN6PR57968__fill_aIiEENS_11__enable_ifIXntsr16__is_scalar_typeIT_EE7__valueEvE6__typeEv
+typename __enable_if<!__is_scalar_type<T>::__value, void>::__type __fill_a() { };
+
+void f() { __fill_a<int>(); }
+}
+
+namespace Expressions {
+// Unary operators.
+
+// CHECK-LABEL: define weak_odr void @_ZN11Expressions2f1ILi1EEEvPAplngT_Li2E_i
+template <int i> void f1(int (*)[(-i) + 2]) { };
+template void f1<1>(int (*)[1]);
+
+// CHECK-LABEL: define weak_odr void @_ZN11Expressions2f2ILi1EEEvPApsT__i
+template <int i> void f2(int (*)[+i]) { };
+template void f2<1>(int (*)[1]);
+
+// Binary operators.
+
+// CHECK-LABEL: define weak_odr void @_ZN11Expressions2f3ILi1EEEvPAplT_T__i
+template <int i> void f3(int (*)[i+i]) { };
+template void f3<1>(int (*)[2]);
+
+// CHECK-LABEL: define weak_odr void @_ZN11Expressions2f4ILi1EEEvPAplplLi2ET_T__i
+template <int i> void f4(int (*)[2 + i+i]) { };
+template void f4<1>(int (*)[4]);
+
+// The ternary operator.
+// CHECK-LABEL: define weak_odr void @_ZN11Expressions2f4ILb1EEEvPAquT_Li1ELi2E_i
+template <bool b> void f4(int (*)[b ? 1 : 2]) { };
+template void f4<true>(int (*)[1]);
+}
+
+struct Ops {
+ Ops& operator+(const Ops&);
+ Ops& operator-(const Ops&);
+ Ops& operator&(const Ops&);
+ Ops& operator*(const Ops&);
+
+ void *v;
+};
+
+// CHECK-LABEL: define dereferenceable({{[0-9]+}}) %struct.Ops* @_ZN3OpsplERKS_
+Ops& Ops::operator+(const Ops&) { return *this; }
+// CHECK-LABEL: define dereferenceable({{[0-9]+}}) %struct.Ops* @_ZN3OpsmiERKS_
+Ops& Ops::operator-(const Ops&) { return *this; }
+// CHECK-LABEL: define dereferenceable({{[0-9]+}}) %struct.Ops* @_ZN3OpsanERKS_
+Ops& Ops::operator&(const Ops&) { return *this; }
+// CHECK-LABEL: define dereferenceable({{[0-9]+}}) %struct.Ops* @_ZN3OpsmlERKS_
+Ops& Ops::operator*(const Ops&) { return *this; }
+
+// PR5861
+namespace PR5861 {
+template<bool> class P;
+template<> class P<true> {};
+
+template<template <bool> class, bool>
+struct Policy { };
+
+template<typename T, typename = Policy<P, true> > class Alloc
+{
+ T *allocate(int, const void*) { return 0; }
+};
+
+// CHECK-LABEL: define weak_odr i8* @_ZN6PR58615AllocIcNS_6PolicyINS_1PELb1EEEE8allocateEiPKv
+template class Alloc<char>;
+}
+
+// CHECK-LABEL: define void @_Z1fU13block_pointerFiiiE
+void f(int (^)(int, int)) { }
+
+void pr5966_foo() {
+ extern int pr5966_i;
+ pr5966_i = 0;
+}
+
+static int pr5966_j;
+
+void pr5966_bar() {
+ pr5966_j = 0;
+}
+
+namespace test0 {
+ int ovl(int x);
+ char ovl(double x);
+
+ template <class T> void f(T, char (&buffer)[sizeof(ovl(T()))]) {}
+
+ void test0() {
+ char buffer[1];
+ f(0.0, buffer);
+ }
+ // CHECK-LABEL: define void @_ZN5test05test0Ev()
+ // CHECK-LABEL: define linkonce_odr void @_ZN5test01fIdEEvT_RAszcl3ovlcvS1__EE_c(
+
+ void test1() {
+ char buffer[sizeof(int)];
+ f(1, buffer);
+ }
+ // CHECK-LABEL: define void @_ZN5test05test1Ev()
+ // CHECK-LABEL: define linkonce_odr void @_ZN5test01fIiEEvT_RAszcl3ovlcvS1__EE_c(
+
+ template <class T> void g(char (&buffer)[sizeof(T() + 5.0f)]) {}
+ void test2() {
+ char buffer[sizeof(float)];
+ g<float>(buffer);
+ }
+ // CHECK-LABEL: define linkonce_odr void @_ZN5test01gIfEEvRAszplcvT__ELf40a00000E_c(
+
+ template <class T> void h(char (&buffer)[sizeof(T() + 5.0)]) {}
+ void test3() {
+ char buffer[sizeof(double)];
+ h<float>(buffer);
+ }
+ // CHECK-LABEL: define linkonce_odr void @_ZN5test01hIfEEvRAszplcvT__ELd4014000000000000E_c(
+
+ template <class T> void j(char (&buffer)[sizeof(T().buffer)]) {}
+ struct A { double buffer[128]; };
+ void test4() {
+ char buffer[1024];
+ j<A>(buffer);
+ }
+ // CHECK-LABEL: define linkonce_odr void @_ZN5test01jINS_1AEEEvRAszdtcvT__E6buffer_c(
+
+ template <class T> void k(char (&buffer)[sizeof(T() + 0.0f)]) {}
+ void test5() {
+ char buffer[sizeof(float)];
+ k<float>(buffer);
+ }
+ // CHECK-LABEL: define linkonce_odr void @_ZN5test01kIfEEvRAszplcvT__ELf00000000E_c(
+
+}
+
+namespace test1 {
+ template<typename T> struct X { };
+ template<template<class> class Y, typename T> void f(Y<T>) { }
+ // CHECK-LABEL: define weak_odr void @_ZN5test11fINS_1XEiEEvT_IT0_E
+ template void f(X<int>);
+}
+
+// CHECK-LABEL: define internal void @_ZL27functionWithInternalLinkagev()
+static void functionWithInternalLinkage() { }
+void g() { functionWithInternalLinkage(); }
+
+namespace test2 {
+ template <class T> decltype(((T*) 0)->member) read_member(T& obj) {
+ return obj.member;
+ }
+
+ struct A { int member; } obj;
+ int test() {
+ return read_member(obj);
+ }
+
+ // CHECK-LABEL: define linkonce_odr i32 @_ZN5test211read_memberINS_1AEEEDtptcvPT_Li0E6memberERS2_(
+}
+
+// rdar://problem/9280586
+namespace test3 {
+ struct AmbiguousBase { int ab; };
+ struct Path1 : AmbiguousBase { float p; };
+ struct Path2 : AmbiguousBase { double p; };
+ struct Derived : Path1, Path2 { };
+
+ // CHECK-LABEL: define linkonce_odr i32 @_ZN5test38get_ab_1INS_7DerivedEEEDtptcvPT_Li0Esr5Path1E2abERS2_(
+ template <class T> decltype(((T*) 0)->Path1::ab) get_ab_1(T &ref) { return ref.Path1::ab; }
+
+ // CHECK-LABEL: define linkonce_odr i32 @_ZN5test38get_ab_2INS_7DerivedEEEDtptcvPT_Li0Esr5Path2E2abERS2_(
+ template <class T> decltype(((T*) 0)->Path2::ab) get_ab_2(T &ref) { return ref.Path2::ab; }
+
+ // CHECK-LABEL: define linkonce_odr float @_ZN5test37get_p_1INS_7DerivedEEEDtptcvPT_Li0Esr5Path1E1pERS2_(
+ template <class T> decltype(((T*) 0)->Path1::p) get_p_1(T &ref) { return ref.Path1::p; }
+
+ // CHECK-LABEL: define linkonce_odr double @_ZN5test37get_p_2INS_7DerivedEEEDtptcvPT_Li0Esr5Path2E1pERS2_(
+ template <class T> decltype(((T*) 0)->Path2::p) get_p_2(T &ref) { return ref.Path2::p; }
+
+ Derived obj;
+ void test() {
+ get_ab_1(obj);
+ get_ab_2(obj);
+ get_p_1(obj);
+ get_p_2(obj);
+ }
+}
+
+// CHECK-LABEL: define void @_ZN5test41gEPNS_3zedIXadL_ZNS_3foo3barEEEEE
+namespace test4 {
+ struct foo { int bar; };
+ template <int (foo::*)>
+ struct zed {};
+ void g(zed<&foo::bar>*)
+ {}
+}
+// CHECK-LABEL: define void @_ZN5test51gEPNS_3zedIXadL_ZNS_3foo3barEEEEE
+namespace test5 {
+ struct foo { static int bar; };
+ template <int *>
+ struct zed {};
+ void g(zed<&foo::bar>*)
+ {}
+}
+// CHECK-LABEL: define void @_ZN5test61gEPNS_3zedIXadL_ZNS_3foo3barEvEEEE
+namespace test6 {
+ struct foo { int bar(); };
+ template <int (foo::*)()>
+ struct zed {};
+ void g(zed<&foo::bar>*)
+ {}
+}
+// CHECK-LABEL: define void @_ZN5test71gEPNS_3zedIXadL_ZNS_3foo3barEvEEEE
+namespace test7 {
+ struct foo { static int bar(); };
+ template <int (*f)()>
+ struct zed {};
+ void g(zed<&foo::bar>*)
+ {}
+}
+// CHECK-LABEL: define weak_odr void @_ZN5test81AIL_ZNS_1B5valueEEE3incEv
+namespace test8 {
+ template <int &counter> class A { void inc() { counter++; } };
+ class B { public: static int value; };
+ template class A<B::value>;
+}
+// CHECK: declare void @_ZN5test91fIiNS_3barEEEvRKNT0_3baz1XE
+namespace test9 {
+ template<class T>
+ struct foo {
+ typedef T X;
+ };
+ struct bar {
+ typedef foo<int> baz;
+ };
+ template <class zaz, class zed>
+ void f(const typename zed::baz::X&);
+ void g() {
+ f<int, bar>( 0);
+ }
+}
+
+// <rdar://problem/7825453>
+namespace test10 {
+ template <char P1> struct S {};
+ template <char P2> void f(struct S<false ? 'a' : P2> ) {}
+
+ // CHECK-LABEL: define weak_odr void @_ZN6test101fILc3EEEvNS_1SIXquLb0ELc97ET_EEE(
+ template void f<(char) 3>(struct S<3>);
+}
+
+namespace test11 {
+ // CHECK: @_ZN6test111fEz
+ void f(...) { }
+
+ struct A {
+ void f(...);
+ };
+
+ // CHECK: @_ZN6test111A1fEz
+ void A::f(...) { }
+}
+
+namespace test12 {
+
+ // CHECK: _ZN6test121fENS_1AILt33000EEE
+ template <unsigned short> struct A { };
+ void f(A<33000>) { }
+}
+
+// PR7446
+namespace test13 {
+ template <template <class> class T> class A {};
+ template <class U> class B {};
+
+ template <template<class> class T> void foo(const A<T> &a) {}
+
+ // CHECK-LABEL: define weak_odr void @_ZN6test133fooINS_1BEEEvRKNS_1AIT_EE(
+ template void foo(const A<B> &a);
+}
+
+namespace test14 {
+ extern "C" {
+ struct S {
+ static int a(), x;
+ };
+ // CHECK-LABEL: define i32 @_ZN6test141S1aEv
+ // CHECK: load i32, i32* @_ZN6test141S1xE
+ int S::a() { return S::x; }
+ }
+}
+
+// rdar://problem/8204122
+namespace test15 {
+ enum E { e = 3 };
+ template <int I> struct S {};
+
+ template <int I> void f(S<I + e>) {}
+
+ // CHECK-LABEL: define weak_odr void @_ZN6test151fILi7EEEvNS_1SIXplT_LNS_1EE3EEEE(
+ template void f<7>(S<7 + e>);
+}
+
+// rdar://problem/8302148
+namespace test17 {
+ template <int N> struct A {};
+
+ struct B {
+ static int foo(void);
+ };
+
+ template <class T> A<sizeof(T::foo())> func(void);
+
+ // CHECK-LABEL: define void @_ZN6test174testEv()
+ // CHECK: call {{.*}} @_ZN6test174funcINS_1BEEENS_1AIXszclsrT_3fooEEEEv()
+ void test() {
+ func<B>();
+ }
+}
+
+// PR7891
+namespace test18 {
+ struct A {
+ int operator+();
+ int operator-();
+ int operator*();
+ int operator&();
+ };
+ template <int (A::*)()> struct S {};
+
+ template <typename T> void f(S<&T::operator+>) {}
+ template void f<A>(S<&A::operator+>);
+
+ template <typename T> void f(S<&T::operator- >) {}
+ template void f<A>(S<&A::operator- >);
+
+ template <typename T> void f(S<&T::operator*>) {}
+ template void f<A>(S<&A::operator*>);
+
+ template <typename T> void f(S<&T::operator&>) {}
+ template void f<A>(S<&A::operator&>);
+
+ // CHECK-LABEL: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_onplEEE
+ // CHECK-LABEL: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_onmiEEE
+ // CHECK-LABEL: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_onmlEEE
+ // CHECK-LABEL: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_onanEEE
+}
+
+// rdar://problem/8332117
+namespace test19 {
+ struct A {
+ template <typename T> int f();
+ int operator+();
+ operator int();
+ template <typename T> int operator-();
+ };
+
+ template <int (A::*)()> struct S {};
+
+ template <typename T> void g (S<&T::template f<int> >) {}
+ template <typename T> void g (S<&T::operator+ >) {}
+ template <typename T> void g (S<&T::operator int>) {}
+ template <typename T> void g (S<&T::template operator- <double> >) {}
+
+ // CHECK-LABEL: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_1fIiEEEE(
+ template void g<A>(S<&A::f<int> >);
+ // CHECK-LABEL: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_onplEEE(
+ template void g<A>(S<&A::operator+>);
+ // CHECK-LABEL: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_oncviEEE(
+ template void g<A>(S<&A::operator int>);
+ // CHECK-LABEL: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_onmiIdEEEE(
+ template void g<A>(S<&A::operator-<double> >);
+}
+
+namespace test20 {
+ template <class T> T *f(const T&);
+ template <class T> T *f(T*);
+
+ // CHECK-LABEL: define weak_odr void @_ZN6test205test0IiEEvDTcl1fIPT_ELi0EEE(
+ template <class T> void test0(decltype(f<T*>(0))) {}
+ template void test0<int>(decltype(f<int*>(0)));
+
+ // CHECK-LABEL: define weak_odr void @_ZN6test205test1IiEEvDTcl1fIEcvT__EEE(
+ template <class T> void test1(decltype(f<>(T()))) {}
+ template void test1<int>(decltype(f<>(int())));
+}
+
+// rdar:// 8620510
+namespace test21 {
+ // CHECK-LABEL: define void @_ZN6test2112vla_arg_funcEiPA_i(
+ void vla_arg_func(int X, int a[X][X]) {}
+}
+
+namespace test22 {
+ // CHECK-LABEL: define void @_ZN6test221fEDn(
+ void f(decltype(nullptr)) { }
+}
+
+// rdar://problem/8913416
+namespace test23 {
+ typedef void * const vpc;
+
+ // CHECK-LABEL: define void @_ZN6test231fERA10_KPv(
+ void f(vpc (&)[10]) {}
+
+ typedef vpc vpca5[5];
+ void f(vpca5 volatile (&)[10]) {}
+ // CHECK-LABEL: define void @_ZN6test231fERA10_A5_VKPv(
+}
+
+namespace test24 {
+ void test0() {
+ extern int foo();
+ // CHECK: call i32 @_ZN6test243fooEv()
+ foo();
+ }
+
+ static char bar() {}
+ void test1() {
+ // CHECK: call signext i8 @_ZN6test24L3barEv()
+ bar();
+ }
+}
+
+// rdar://problem/8806641
+namespace test25 {
+ template <void (*fn)()> struct A {
+ static void call() { fn(); }
+ };
+ void foo();
+ void test() {
+ // CHECK: call void @_ZN6test251AIXadL_ZNS_3fooEvEEE4callEv()
+ A<foo>::call();
+ }
+}
+
+namespace test26 {
+ template <template <class> class T> void foo(decltype(T<float>::object) &object) {}
+
+ template <class T> struct holder { static T object; };
+
+ void test() {
+ float f;
+
+ // CHECK: call void @_ZN6test263fooINS_6holderEEEvRDtsrT_IfE6objectE(
+ foo<holder>(f);
+ }
+}
+
+namespace test27 {
+ struct A {
+ struct inner {
+ float object;
+ };
+
+ float meth();
+ };
+ typedef A Alias;
+
+ template <class T> void a(decltype(T::inner::object) &object) {}
+ template <class T> void b(decltype(T().Alias::meth()) &object) {}
+
+ void test() {
+ float f;
+ // CHECK: call void @_ZN6test271aINS_1AEEEvRDtsrNT_5innerE6objectE(
+ a<A>(f);
+ // CHECK: call void @_ZN6test271bINS_1AEEEvRDTcldtcvT__Esr5AliasE4methEE(
+ b<A>(f);
+ }
+}
+
+// An injected class name type in a unresolved-name.
+namespace test28 {
+ template <class T> struct A {
+ enum { bit };
+ };
+
+ template <class T> void foo(decltype(A<T>::A::bit) x);
+
+ void test() {
+ foo<char>(A<char>::bit);
+ // CHECK: call void @_ZN6test283fooIcEEvDtsr1AIT_E1AE3bitE(
+ }
+}
+
+// An enclosing template type parameter in an unresolved-name.
+namespace test29 {
+ template <class T> struct A {
+ template <class U> static void foo(decltype(T::fn(U())) x);
+ };
+ struct B { static int fn(int); static long fn(long); };
+
+ void test() {
+ A<B>::foo<int>(0);
+ // CHECK: call void @_ZN6test291AINS_1BEE3fooIiEEvDTclsrS1_2fncvT__EEE(
+ }
+}
+
+// An enclosing template template parameter in an unresolved-name.
+namespace test30 {
+ template <template <class> class T> struct A {
+ template <class U> static void foo(decltype(T<U>::fn()) x);
+ };
+ template <class T> struct B { static T fn(); };
+
+ void test() {
+ A<B>::foo<int>(0);
+ // CHECK: call void @_ZN6test301AINS_1BEE3fooIiEEvDTclsrS1_IT_EE2fnEE(
+ }
+}
+
+namespace test31 { // instantiation-dependent mangling of decltype
+ int x;
+ template<class T> auto f1(T p)->decltype(x) { return 0; }
+ // The return type in the mangling of the template signature
+ // is encoded as "i".
+ template<class T> auto f2(T p)->decltype(p) { return 0; }
+ // The return type in the mangling of the template signature
+ // is encoded as "Dtfp_E".
+ void g(int);
+ template<class T> auto f3(T p)->decltype(g(p)) {}
+
+ // CHECK-LABEL: define weak_odr i32 @_ZN6test312f1IiEEiT_(
+ template int f1(int);
+ // CHECK-LABEL: define weak_odr i32 @_ZN6test312f2IiEEDtfp_ET_
+ template int f2(int);
+ // CHECK-LABEL: define weak_odr void @_ZN6test312f3IiEEDTcl1gfp_EET_
+ template void f3(int);
+}
+
+// PR10205
+namespace test32 {
+ template<typename T, int=T::value> struct A {
+ typedef int type;
+ };
+ struct B { enum { value = 4 }; };
+
+ template <class T> typename A<T>::type foo() { return 0; }
+ void test() {
+ foo<B>();
+ // CHECK: call i32 @_ZN6test323fooINS_1BEEENS_1AIT_XsrS3_5valueEE4typeEv()
+ }
+}
+
+namespace test33 {
+ template <class T> struct X {
+ enum { value = T::value };
+ };
+
+ template<typename T, int=X<T>::value> struct A {
+ typedef int type;
+ };
+ struct B { enum { value = 4 }; };
+
+ template <class T> typename A<T>::type foo() { return 0; }
+
+ void test() {
+ foo<B>();
+ // CHECK: call i32 @_ZN6test333fooINS_1BEEENS_1AIT_Xsr1XIS3_EE5valueEE4typeEv()
+ }
+}
+
+namespace test34 {
+ // Mangling for instantiation-dependent decltype expressions.
+ template<typename T>
+ void f(decltype(sizeof(decltype(T() + T())))) {}
+
+ // CHECK-LABEL: define weak_odr void @_ZN6test341fIiEEvDTstDTplcvT__EcvS1__EEE
+ template void f<int>(decltype(sizeof(1)));
+
+ // Mangling for non-instantiation-dependent sizeof expressions.
+ template<unsigned N>
+ void f2(int (&)[N + sizeof(int*)]) {}
+
+ // CHECK-LABEL: define weak_odr void @_ZN6test342f2ILj4EEEvRAplT_Lm8E_i
+ template void f2<4>(int (&)[4 + sizeof(int*)]);
+
+ // Mangling for non-instantiation-dependent sizeof expressions
+ // involving an implicit conversion of the result of the sizeof.
+ template<unsigned long long N>
+ void f3(int (&)[N + sizeof(int*)]) {}
+
+ // CHECK-LABEL: define weak_odr void @_ZN6test342f3ILy4EEEvRAplT_Ly8E_i
+ template void f3<4>(int (&)[4 + sizeof(int*)]);
+
+ // Mangling for instantiation-dependent sizeof() expressions as
+ // template arguments.
+ template<unsigned> struct A { };
+
+ template<typename T> void f4(::test34::A<sizeof(sizeof(decltype(T() + T())))>) { }
+
+ // CHECK-LABEL: define weak_odr void @_ZN6test342f4IiEEvNS_1AIXszstDTplcvT__EcvS2__EEEEE
+ template void f4<int>(A<sizeof(sizeof(int))>);
+}
+
+namespace test35 {
+ // Dependent operator names of unknown arity.
+ struct A {
+ template<typename U> A operator+(U) const;
+ };
+
+ template<typename T>
+ void f1(decltype(sizeof(&T::template operator+<int>))) {}
+
+ // CHECK-LABEL: define weak_odr void @_ZN6test352f1INS_1AEEEvDTszadsrT_onplIiEE
+ template void f1<A>(__SIZE_TYPE__);
+}
+
+namespace test36 {
+ template<unsigned> struct A { };
+
+ template<typename ...Types>
+ auto f1(Types... values) -> A<sizeof...(values)> { }
+
+ // CHECK: define weak_odr {{.*}} @_ZN6test362f1IJifEEENS_1AIXsZfp_EEEDpT_
+ template A<2> f1(int, float);
+}
+
+namespace test37 {
+ struct foo {
+ struct {
+ } a;
+ typedef struct { } b;
+ typedef struct { } *c;
+ struct {
+ } d;
+ };
+ template<typename T> void func(T) { }
+ void test() {
+ // CHECK-LABEL: define linkonce_odr void @_ZN6test374funcINS_3fooUt_EEEvT_
+ func(foo().a);
+ // CHECK-LABEL: define linkonce_odr void @_ZN6test374funcINS_3fooUt0_EEEvT_
+ func(*foo::c());
+ // CHECK-LABEL: define linkonce_odr void @_ZN6test374funcINS_3fooUt1_EEEvT_
+ func(foo().d);
+ }
+}
+
+// CHECK-LABEL: define void @_Z6ASfuncPU3AS3i
+void ASfunc(__attribute__((address_space(3))) int* x) {}
+
+namespace test38 {
+ // CHECK-LABEL: define linkonce_odr void @_ZN6test384funcINS_3fooUt_EEEvT_
+ typedef struct {
+ struct {
+ } a;
+ } foo;
+
+ template <typename T> void func(T) {}
+ void test() { func(foo().a); }
+}
+
+namespace test39 {
+ // CHECK-LABEL: define internal void @"_ZN6test394funcINS_3$_03$_1EEEvT_"
+ typedef struct {
+ struct {} a;
+ } *foo;
+ template<typename T> void func(T) {}
+ void test() {
+ foo x;
+ func(x->a);
+ }
+}
+
+namespace test40 {
+ // CHECK: i32* {{.*}} @_ZZN6test401fEvE1a_0
+ void h(int&);
+ inline void f() {
+ if (0) {
+ static int a;
+ }
+ static int a;
+ h(a);
+ };
+ void g() { f(); }
+}
+
+namespace test41 {
+ // CHECK: define linkonce_odr void @_ZN6test414funcINS_1XEEEvNS_3fooILi20ES1_EE
+ template <int i, class T> struct foo {
+ template <class T2 = T> friend void func(foo x) {}
+ };
+
+ struct X {};
+
+ void g() { func(foo<20, X>()); }
+}
+
+namespace test42 {
+ // CHECK: define linkonce_odr void @_ZN6test424funcINS_1XEEEvNS_3fooILi20ES1_EE
+ template <int i, template <class> class T> struct foo {
+ template <template <class> class T2 = T> friend void func(foo x) {}
+ };
+
+ template <class V> struct X {
+ };
+
+ void g() { func(foo<20, X>()); }
+}
+
+namespace test43 {
+ // CHECK-LABEL: define void @_ZN6test431gEPNS_3zedIXadL_ZNS_3fooUt_3barEEEEE
+ struct foo { union { int bar; }; };
+ template <int (foo::*)>
+ struct zed {};
+ void g(zed<&foo::bar>*)
+ {}
+}
+
+namespace test44 {
+ struct foo { void bar() __restrict { }; } obj;
+
+ void f() {
+ obj.bar();
+ }
+ // CHECK-LABEL: define linkonce_odr void @_ZN6test443foo3barEv(%"struct.test44::foo"* %this)
+}
+
+namespace test45 {
+ struct S {
+ enum e {};
+ };
+ template <typename T>
+ void f(enum T::e *) {}
+ template void f<S>(S::e *);
+ // CHECK-LABEL: define weak_odr void @_ZN6test451fINS_1SEEEvPTeNT_1eE(i32*)
+}
+
+namespace test46 {
+ struct S {
+ struct s {};
+ };
+ template <typename T>
+ void f(struct T::s *) {}
+ template void f<S>(S::s *);
+ // CHECK-LABEL: define weak_odr void @_ZN6test461fINS_1SEEEvPTsNT_1sE(%"struct.test46::S::s"*)
+}
+
+namespace test47 {
+ struct S {
+ class c {};
+ };
+ template <typename T>
+ void f(class T::c *) {}
+ template void f<S>(S::c *);
+ // CHECK-LABEL: define weak_odr void @_ZN6test471fINS_1SEEEvPTsNT_1cE(%"class.test47::S::c"*)
+}
+
+namespace test48 {
+ struct S {
+ union u {};
+ };
+ template <typename T>
+ void f(union T::u *) {}
+ template void f<S>(S::u *);
+ // CHECK-LABEL: define weak_odr void @_ZN6test481fINS_1SEEEvPTuNT_1uE(%"union.test48::S::u"*)
+}
+
+namespace test49 {
+ template <int>
+ struct S {};
+
+ template <template <int> class T>
+ T<3> fin(T<3>);
+
+ auto v = fin<S>;
+ // CHECK-LABEL: declare void @_ZN6test493finINS_1SEEET_ILi3EES3_()
+}
+
+namespace test50 {
+ template <int>
+ struct S {};
+
+ template <template <int> class T>
+ T<3> fin(T<4>);
+
+ auto v = fin<S>;
+ // CHECK-LABEL: declare void @_ZN6test503finINS_1SEEET_ILi3EES2_ILi4EE()
+}
+
+namespace test51 {
+ template <typename T>
+ decltype(T().~T()) fun() {}
+ template void fun<int>();
+ // CHECK-LABEL: @_ZN6test513funIiEEDTcldtcvT__EdnS1_EEv
+ template void fun<X>();
+ // CHECK-LABEL: @_ZN6test513funI1XEEDTcldtcvT__EdnS2_EEv
+ template void fun<S1<int> >();
+ // CHECK-LABEL: @_ZN6test513funI2S1IiEEEDTcldtcvT__EdnS3_EEv
+
+ enum E {};
+ template <typename T>
+ struct X {
+ struct Y {};
+ };
+
+ template <typename T>
+ decltype(S1<T>().~S1<T>()) fun1() {};
+ template <typename U, typename T>
+ decltype(U().~S1<T>()) fun2() {}
+ template <typename U, typename T>
+ decltype(S1<T>().~U()) fun3() {}
+ template <typename T>
+ decltype(S1<T>().~S1<T>(), S1<T>().~S1<T>()) fun4() {};
+ template <typename T>
+ decltype(S1<int>().~S1<T>()) fun5(){};
+ template <template <typename T> class U>
+ decltype(S1<int>().~U<int>()) fun6(){};
+ template <typename T>
+ decltype(E().E::~T()) fun7() {}
+ template <template <typename> class U>
+ decltype(X<int>::Y().U<int>::Y::~Y()) fun8() {}
+ template void fun1<int>();
+ // CHECK-LABEL: @_ZN6test514fun1IiEEDTcldtcv2S1IT_E_Edn2S1IS2_EEEv
+ template void fun2<S1<int>, int>();
+ // CHECK-LABEL: @_ZN6test514fun2I2S1IiEiEEDTcldtcvT__Edn2S1IT0_EEEv
+ template void fun3<S1<int>, int>();
+ // CHECK-LABEL: @_ZN6test514fun3I2S1IiEiEEDTcldtcvS1_IT0_E_EdnT_EEv
+ template void fun4<int>();
+ // CHECK-LABEL: @_ZN6test514fun4IiEEDTcmcldtcv2S1IT_E_Edn2S1IS2_EEcldtcvS3__Edn2S1IS2_EEEv
+ template void fun5<int>();
+ // CHECK-LABEL: @_ZN6test514fun5IiEEDTcldtcv2S1IiE_Edn2S1IT_EEEv
+ template void fun6<S1>();
+ // CHECK-LABEL: @_ZN6test514fun6I2S1EEDTcldtcvS1_IiE_EdnT_IiEEEv
+ template void fun7<E>();
+ // CHECK-LABEL: @_ZN6test514fun7INS_1EEEEDTcldtcvS1__Esr1EEdnT_EEv
+ template void fun8<X>();
+}
+
+namespace test52 {
+struct X {};
+void operator+(X);
+template <typename... T>
+auto f4(T... x) -> decltype(operator+(x...));
+// CHECK-LABEL: @_ZN6test522f4IJNS_1XEEEEDTclonplspfp_EEDpT_
+void use() { f4(X{}); }
+}
+
+namespace test53 {
+struct c {
+ using t1 = struct { int z; };
+ using t2 = struct { double z; };
+ using t3 = struct { float z; };
+ using t4 = struct { float z; };
+
+ __attribute__((used)) c(t1) {}
+ __attribute__((used)) c(t2) {}
+ __attribute__((used)) c(t3) {}
+ __attribute__((used)) c(t4) {}
+ // CHECK-LABEL: @_ZN6test531cC2ENS0_2t1E
+ // CHECK-LABEL: @_ZN6test531cC2ENS0_2t2E
+ // CHECK-LABEL: @_ZN6test531cC2ENS0_2t3E
+ // CHECK-LABEL: @_ZN6test531cC2ENS0_2t4E
+};
+}
+
+namespace test54 {
+struct c {
+ using t1 = struct { int z; } *;
+ using t2 = struct { double z; } *;
+
+ __attribute__((used)) c(t1) {}
+ __attribute__((used)) c(t2) {}
+ // CHECK-LABEL: @_ZN6test541cC2EPNS0_Ut_E
+ // CHECK-LABEL: @_ZN6test541cC2EPNS0_Ut0_E
+};
+}
+
+namespace test55 {
+enum E { R };
+
+template <typename T>
+void fn(T, __underlying_type(T)) {}
+
+template void fn<E>(E, __underlying_type(E));
+// CHECK-LABEL: @_ZN6test552fnINS_1EEEEvT_U3eutS2_
+}
+
+namespace test56 {
+ struct A { A *operator->(); int n; } a;
+ template<int N> void f(decltype(a->n + N)) {}
+ // CHECK-LABEL: @_ZN6test561fILi0EEEvDTplptL_ZNS_1aEE1nT_E
+ template void f<0>(int);
+}
+
+namespace test57 {
+ struct X { template <int N> int f(); } x;
+ template<int N> void f(decltype(x.f<0>() + N)) {}
+ // CHECK-LABEL: @_ZN6test571fILi0EEEvDTplcldtL_ZNS_1xEE1fIXLi0EEEET_E
+ template void f<0>(int);
+}
+
+namespace test58 {
+ struct State {
+ bool m_fn1();
+ } a;
+ template <class T> struct identity { typedef T type; };
+ struct A {
+ template <typename T> A(T, bool (identity<T>::type::*)());
+ };
+ // CHECK-LABEL: @_ZN6test581AC1INS_5StateEEET_MNS_8identityIS3_E4typeEFbvE
+ void fn1() { A(a, &State::m_fn1); }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/member-alignment.cpp b/src/llvm-project/clang/test/CodeGenCXX/member-alignment.cpp
new file mode 100644
index 0000000..ff6bb44
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/member-alignment.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple %s -o - | \
+// RUN: FileCheck -check-prefix CHECK-ITANIUM %s
+// RUN: %clang_cc1 -emit-llvm -triple wasm32-unknown-unknown %s -o - | \
+// RUN: FileCheck -check-prefix CHECK-WEBASSEMBLY32 %s
+// RUN: %clang_cc1 -emit-llvm -triple wasm64-unknown-unknown %s -o - | \
+// RUN: FileCheck -check-prefix CHECK-WEBASSEMBLY64 %s
+
+// rdar://7268289
+
+class t {
+public:
+ virtual void foo(void);
+ void bar(void);
+};
+
+void
+t::bar(void) {
+// CHECK-ITANIUM: @_ZN1t3barEv({{.*}}) #0 align 2 {
+// CHECK-WEBASSEMBLY32: @_ZN1t3barEv({{.*}}) #0 {
+// CHECK-WEBASSEMBLY64: @_ZN1t3barEv({{.*}}) #0 {
+}
+
+void
+t::foo(void) {
+// CHECK-ITANIUM: @_ZN1t3fooEv({{.*}}) unnamed_addr #0 align 2 {
+// CHECK-WEBASSEMBLY32: @_ZN1t3fooEv({{.*}}) unnamed_addr #0 {
+// CHECK-WEBASSEMBLY64: @_ZN1t3fooEv({{.*}}) unnamed_addr #0 {
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/member-call-parens.cpp b/src/llvm-project/clang/test/CodeGenCXX/member-call-parens.cpp
new file mode 100644
index 0000000..3def43e
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/member-call-parens.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -emit-llvm-only -verify %s
+// expected-no-diagnostics
+
+struct A { int a(); };
+typedef int B;
+void a() {
+ A x;
+ ((x.a))();
+ ((x.*&A::a))();
+ B y;
+ // FIXME: Sema doesn't like this for some reason...
+ //(y.~B)();
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/member-data-pointers.cpp b/src/llvm-project/clang/test/CodeGenCXX/member-data-pointers.cpp
new file mode 100644
index 0000000..d347366
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/member-data-pointers.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=x86_64-unknown-unknown | FileCheck -check-prefix GLOBAL-LP64 %s
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=armv7-unknown-unknown | FileCheck -check-prefix GLOBAL-LP32 %s
+
+struct A;
+typedef int A::*param_t;
+struct {
+ const char *name;
+ param_t par;
+} *ptr;
+void test_ptr() { (void) ptr; } // forced use
+
+// GLOBAL-LP64: type { i8*, i64 }
+// GLOBAL-LP32: type { i8*, i32 }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/member-expr-references-variable.cpp b/src/llvm-project/clang/test/CodeGenCXX/member-expr-references-variable.cpp
new file mode 100644
index 0000000..8c1dded
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/member-expr-references-variable.cpp
@@ -0,0 +1,104 @@
+// RUN: %clang_cc1 -std=c++11 %s -triple x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+struct Agg { const char * x; const char * y; constexpr Agg() : x(0), y(0) {} };
+
+struct Struct {
+ constexpr static const char *name = "foo";
+
+ constexpr static __complex float complexValue = 42.0;
+
+ static constexpr const Agg &agg = Agg();
+
+ Struct();
+ Struct(int x);
+};
+
+void use(int n, const char *c);
+
+Struct *getPtr();
+
+// CHECK: @[[STR:.*]] = private unnamed_addr constant [4 x i8] c"foo\00", align 1
+
+void scalarStaticVariableInMemberExpr(Struct *ptr, Struct &ref) {
+ use(1, Struct::name);
+// CHECK: call void @_Z3useiPKc(i32 1, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[STR]], i32 0, i32 0))
+ Struct s;
+ use(2, s.name);
+// CHECK: call void @_Z3useiPKc(i32 2, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[STR]], i32 0, i32 0))
+ use(3, ptr->name);
+// CHECK: load %struct.Struct*, %struct.Struct** %{{.*}}, align 8
+// CHECK: call void @_Z3useiPKc(i32 3, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[STR]], i32 0, i32 0))
+ use(4, ref.name);
+// CHECK: load %struct.Struct*, %struct.Struct** %{{.*}}, align 8
+// CHECK: call void @_Z3useiPKc(i32 4, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[STR]], i32 0, i32 0))
+ use(5, Struct(2).name);
+// CHECK: call void @_ZN6StructC1Ei(%struct.Struct* %{{.*}}, i32 2)
+// CHECK: call void @_Z3useiPKc(i32 5, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[STR]], i32 0, i32 0))
+ use(6, getPtr()->name);
+// CHECK: call %struct.Struct* @_Z6getPtrv()
+// CHECK: call void @_Z3useiPKc(i32 6, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[STR]], i32 0, i32 0))
+}
+
+void use(int n, __complex float v);
+
+void complexStaticVariableInMemberExpr(Struct *ptr, Struct &ref) {
+ use(1, Struct::complexValue);
+// CHECK: store float 4.200000e+01, float* %[[coerce0:.*]].{{.*}}, align 4
+// CHECK: store float 0.000000e+00, float* %[[coerce0]].{{.*}}, align 4
+// CHECK: %[[cast0:.*]] = bitcast { float, float }* %[[coerce0]] to <2 x float>*
+// CHECK: %[[vector0:.*]] = load <2 x float>, <2 x float>* %[[cast0]], align 4
+// CHECK: call void @_Z3useiCf(i32 1, <2 x float> %[[vector0]])
+ Struct s;
+ use(2, s.complexValue);
+// CHECK: store float 4.200000e+01, float* %[[coerce1:.*]].{{.*}}, align 4
+// CHECK: store float 0.000000e+00, float* %[[coerce1]].{{.*}}, align 4
+// CHECK: %[[cast1:.*]] = bitcast { float, float }* %[[coerce1]] to <2 x float>*
+// CHECK: %[[vector1:.*]] = load <2 x float>, <2 x float>* %[[cast1]], align 4
+// CHECK: call void @_Z3useiCf(i32 2, <2 x float> %[[vector1]])
+ use(3, ptr->complexValue);
+// CHECK: load %struct.Struct*, %struct.Struct** %{{.*}}, align 8
+// CHECK: store float 4.200000e+01, float* %[[coerce2:.*]].{{.*}}, align 4
+// CHECK: store float 0.000000e+00, float* %[[coerce2]].{{.*}}, align 4
+// CHECK: %[[cast2:.*]] = bitcast { float, float }* %[[coerce2]] to <2 x float>*
+// CHECK: %[[vector2:.*]] = load <2 x float>, <2 x float>* %[[cast2]], align 4
+// CHECK: call void @_Z3useiCf(i32 3, <2 x float> %[[vector2]])
+ use(4, ref.complexValue);
+// CHECK: load %struct.Struct*, %struct.Struct** %{{.*}}, align 8
+// CHECK: store float 4.200000e+01, float* %[[coerce3:.*]].{{.*}}, align 4
+// CHECK: store float 0.000000e+00, float* %[[coerce3]].{{.*}}, align 4
+// CHECK: %[[cast3:.*]] = bitcast { float, float }* %[[coerce3]] to <2 x float>*
+// CHECK: %[[vector3:.*]] = load <2 x float>, <2 x float>* %[[cast3]], align 4
+// CHECK: call void @_Z3useiCf(i32 4, <2 x float> %[[vector3]])
+ use(5, Struct(2).complexValue);
+// CHECK: call void @_ZN6StructC1Ei(%struct.Struct* %{{.*}}, i32 2)
+// CHECK: store float 4.200000e+01, float* %[[coerce4:.*]].{{.*}}, align 4
+// CHECK: store float 0.000000e+00, float* %[[coerce4]].{{.*}}, align 4
+// CHECK: %[[cast4:.*]] = bitcast { float, float }* %[[coerce4]] to <2 x float>*
+// CHECK: %[[vector4:.*]] = load <2 x float>, <2 x float>* %[[cast4]], align 4
+// CHECK: call void @_Z3useiCf(i32 5, <2 x float> %[[vector4]])
+ use(6, getPtr()->complexValue);
+// CHECK: call %struct.Struct* @_Z6getPtrv()
+// CHECK: store float 4.200000e+01, float* %[[coerce5:.*]].{{.*}}, align 4
+// CHECK: store float 0.000000e+00, float* %[[coerce5]].{{.*}}, align 4
+// CHECK: %[[cast5:.*]] = bitcast { float, float }* %[[coerce5]] to <2 x float>*
+// CHECK: %[[vector5:.*]] = load <2 x float>, <2 x float>* %[[cast5]], align 4
+// CHECK: call void @_Z3useiCf(i32 6, <2 x float> %[[vector5]])
+}
+
+void aggregateRefInMemberExpr(Struct *ptr, Struct &ref) {
+ use(1, Struct::agg.x);
+// CHECK: %[[value0:.*]] = load i8*, i8** getelementptr inbounds (%struct.Agg, %struct.Agg* @_ZGRN6Struct3aggE_, i32 0, i32 0), align 8
+// CHECK: call void @_Z3useiPKc(i32 1, i8* %[[value0]])
+ Struct s;
+ use(2, s.agg.x);
+// CHECK: %[[value1:.*]] = load i8*, i8** getelementptr inbounds (%struct.Agg, %struct.Agg* @_ZGRN6Struct3aggE_, i32 0, i32 0), align 8
+// CHECK: call void @_Z3useiPKc(i32 2, i8* %[[value1]])
+ use(3, ptr->agg.x);
+// CHECK: load %struct.Struct*, %struct.Struct** %{{.*}}, align 8
+// CHECK: %[[value2:.*]] = load i8*, i8** getelementptr inbounds (%struct.Agg, %struct.Agg* @_ZGRN6Struct3aggE_, i32 0, i32 0), align 8
+// CHECK: call void @_Z3useiPKc(i32 3, i8* %[[value2]])
+ use(4, ref.agg.x);
+// CHECK: load %struct.Struct*, %struct.Struct** %{{.*}}, align 8
+// CHECK: %[[value3:.*]] = load i8*, i8** getelementptr inbounds (%struct.Agg, %struct.Agg* @_ZGRN6Struct3aggE_, i32 0, i32 0), align 8
+// CHECK: call void @_Z3useiPKc(i32 4, i8* %[[value3]])
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/member-expressions.cpp b/src/llvm-project/clang/test/CodeGenCXX/member-expressions.cpp
new file mode 100644
index 0000000..bbfa51f
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/member-expressions.cpp
@@ -0,0 +1,86 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin10 | FileCheck %s
+
+// PR5392
+namespace PR5392 {
+struct A
+{
+ static int a;
+};
+
+A a1;
+void f()
+{
+ // CHECK: store i32 10, i32* @_ZN6PR53921A1aE
+ a1.a = 10;
+ // CHECK: store i32 20, i32* @_ZN6PR53921A1aE
+ A().a = 20;
+}
+
+}
+
+struct A {
+ A();
+ ~A();
+ enum E { Foo };
+};
+
+A *g();
+
+void f(A *a) {
+ A::E e1 = a->Foo;
+
+ // CHECK: call %struct.A* @_Z1gv()
+ A::E e2 = g()->Foo;
+ // CHECK: call void @_ZN1AC1Ev(
+ // CHECK: call void @_ZN1AD1Ev(
+ A::E e3 = A().Foo;
+}
+
+namespace test3 {
+struct A {
+ static int foo();
+};
+int f() {
+ return A().foo();
+}
+}
+
+namespace test4 {
+ struct A {
+ int x;
+ };
+ struct B {
+ int x;
+ void foo();
+ };
+ struct C : A, B {
+ };
+
+ extern C *c_ptr;
+
+ // CHECK-LABEL: define i32 @_ZN5test44testEv()
+ int test() {
+ // CHECK: load {{.*}} @_ZN5test45c_ptrE
+ // CHECK-NEXT: bitcast
+ // CHECK-NEXT: getelementptr
+ // CHECK-NEXT: bitcast
+ // CHECK-NEXT: call void @_ZN5test41B3fooEv
+ c_ptr->B::foo();
+
+ // CHECK: load {{.*}} @_ZN5test45c_ptrE
+ // CHECK-NEXT: bitcast
+ // CHECK-NEXT: getelementptr
+ // CHECK-NEXT: bitcast
+ // CHECK-NEXT: getelementptr
+ // CHECK-NEXT: store i32 5
+ c_ptr->B::x = 5;
+
+ // CHECK: load {{.*}} @_ZN5test45c_ptrE
+ // CHECK-NEXT: bitcast
+ // CHECK-NEXT: getelementptr
+ // CHECK-NEXT: bitcast
+ // CHECK-NEXT: getelementptr
+ // CHECK-NEXT: load i32, i32*
+ return c_ptr->B::x;
+ }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/member-function-pointer-calls.cpp b/src/llvm-project/clang/test/CodeGenCXX/member-function-pointer-calls.cpp
new file mode 100644
index 0000000..198119b
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/member-function-pointer-calls.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -O3 -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=x86_64-windows-gnu -emit-llvm -o - | FileCheck %s -check-prefix MINGW64
+struct A {
+ virtual int vf1() { return 1; }
+ virtual int vf2() { return 2; }
+};
+
+int f(A* a, int (A::*fp)()) {
+ return (a->*fp)();
+}
+
+// CHECK-LABEL: define i32 @_Z2g1v()
+// CHECK: ret i32 1
+// MINGW64-LABEL: define dso_local i32 @_Z2g1v()
+// MINGW64: call i32 @_Z1fP1AMS_FivE(%struct.A* %{{.*}}, { i64, i64 }* %{{.*}})
+int g1() {
+ A a;
+ return f(&a, &A::vf1);
+}
+
+// CHECK-LABEL: define i32 @_Z2g2v()
+// CHECK: ret i32 2
+// MINGW64-LABEL: define dso_local i32 @_Z2g2v()
+// MINGW64: call i32 @_Z1fP1AMS_FivE(%struct.A* %{{.*}}, { i64, i64 }* %{{.*}})
+int g2() {
+ A a;
+ return f(&a, &A::vf2);
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/member-function-pointers.cpp b/src/llvm-project/clang/test/CodeGenCXX/member-function-pointers.cpp
new file mode 100644
index 0000000..faeb855
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/member-function-pointers.cpp
@@ -0,0 +1,296 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=x86_64-unknown-unknown | FileCheck -check-prefix CODE-LP64 %s
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=i386-unknown-unknown | FileCheck -check-prefix CODE-LP32 %s
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=x86_64-unknown-unknown | FileCheck -check-prefix GLOBAL-LP64 %s
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=i386-unknown-unknown | FileCheck -check-prefix GLOBAL-LP32 %s
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=armv7-unknown-unknown | FileCheck -check-prefix GLOBAL-ARM %s
+
+// PNaCl uses the same representation of method pointers as ARM.
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=le32-unknown-nacl | FileCheck -check-prefix GLOBAL-ARM %s
+// MIPS uses the same representation of method pointers as ARM.
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=mips-unknown-linux-gnu | FileCheck -check-prefix GLOBAL-ARM %s
+// WebAssembly uses the same representation of method pointers as ARM.
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=wasm32-unknown-unknown | FileCheck -check-prefix GLOBAL-ARM %s
+
+struct A { int a; void f(); virtual void vf1(); virtual void vf2(); };
+struct B { int b; virtual void g(); };
+struct C : B, A { };
+
+void (A::*pa)();
+void (A::*volatile vpa)();
+void (B::*pb)();
+void (C::*pc)();
+
+// GLOBAL-LP64: @pa2 = global { i64, i64 } { i64 ptrtoint (void (%struct.A*)* @_ZN1A1fEv to i64), i64 0 }, align 8
+void (A::*pa2)() = &A::f;
+
+// GLOBAL-LP64: @pa3 = global { i64, i64 } { i64 1, i64 0 }, align 8
+// GLOBAL-LP32: @pa3 = global { i32, i32 } { i32 1, i32 0 }, align 4
+void (A::*pa3)() = &A::vf1;
+
+// GLOBAL-LP64: @pa4 = global { i64, i64 } { i64 9, i64 0 }, align 8
+// GLOBAL-LP32: @pa4 = global { i32, i32 } { i32 5, i32 0 }, align 4
+void (A::*pa4)() = &A::vf2;
+
+// GLOBAL-LP64: @pc2 = global { i64, i64 } { i64 ptrtoint (void (%struct.A*)* @_ZN1A1fEv to i64), i64 16 }, align 8
+void (C::*pc2)() = &C::f;
+
+// GLOBAL-LP64: @pc3 = global { i64, i64 } { i64 1, i64 0 }, align 8
+void (A::*pc3)() = &A::vf1;
+
+void f() {
+ // CODE-LP64: store { i64, i64 } zeroinitializer, { i64, i64 }* @pa
+ pa = 0;
+
+ // Is this okay? What are LLVM's volatile semantics for structs?
+ // CODE-LP64: store volatile { i64, i64 } zeroinitializer, { i64, i64 }* @vpa
+ vpa = 0;
+
+ // CODE-LP64: [[TMP:%.*]] = load { i64, i64 }, { i64, i64 }* @pa, align 8
+ // CODE-LP64: [[TMPADJ:%.*]] = extractvalue { i64, i64 } [[TMP]], 1
+ // CODE-LP64: [[ADJ:%.*]] = add nsw i64 [[TMPADJ]], 16
+ // CODE-LP64: [[RES:%.*]] = insertvalue { i64, i64 } [[TMP]], i64 [[ADJ]], 1
+ // CODE-LP64: store { i64, i64 } [[RES]], { i64, i64 }* @pc, align 8
+ pc = pa;
+
+ // CODE-LP64: [[TMP:%.*]] = load { i64, i64 }, { i64, i64 }* @pc, align 8
+ // CODE-LP64: [[TMPADJ:%.*]] = extractvalue { i64, i64 } [[TMP]], 1
+ // CODE-LP64: [[ADJ:%.*]] = sub nsw i64 [[TMPADJ]], 16
+ // CODE-LP64: [[RES:%.*]] = insertvalue { i64, i64 } [[TMP]], i64 [[ADJ]], 1
+ // CODE-LP64: store { i64, i64 } [[RES]], { i64, i64 }* @pa, align 8
+ pa = static_cast<void (A::*)()>(pc);
+}
+
+void f2() {
+ // CODE-LP64: store { i64, i64 } { i64 ptrtoint (void (%struct.A*)* @_ZN1A1fEv to i64), i64 0 }
+ void (A::*pa2)() = &A::f;
+
+ // CODE-LP64: store { i64, i64 } { i64 1, i64 0 }
+ // CODE-LP32: store { i32, i32 } { i32 1, i32 0 }
+ void (A::*pa3)() = &A::vf1;
+
+ // CODE-LP64: store { i64, i64 } { i64 9, i64 0 }
+ // CODE-LP32: store { i32, i32 } { i32 5, i32 0 }
+ void (A::*pa4)() = &A::vf2;
+}
+
+void f3(A *a, A &ar) {
+ (a->*pa)();
+ (ar.*pa)();
+}
+
+bool f4() {
+ return pa;
+}
+
+// PR5177
+namespace PR5177 {
+ struct A {
+ bool foo(int*) const;
+ } a;
+
+ struct B1 {
+ bool (A::*pmf)(int*) const;
+ const A* pa;
+
+ B1() : pmf(&A::foo), pa(&a) {}
+ bool operator()() const { return (pa->*pmf)(new int); }
+ };
+
+ void bar(B1 b2) { while (b2()) ; }
+}
+
+// PR5138
+namespace PR5138 {
+ struct foo {
+ virtual void bar(foo *);
+ };
+
+ extern "C" {
+ void baz(foo *);
+ }
+
+ void (foo::*ptr1)(void *) = (void (foo::*)(void *))&foo::bar;
+ void (*ptr2)(void *) = (void (*)(void *))&baz;
+
+ void (foo::*ptr3)(void) = (void (foo::*)(void))&foo::bar;
+}
+
+// PR5593
+namespace PR5593 {
+ struct A { };
+
+ bool f(void (A::*f)()) {
+ return f && f;
+ }
+}
+
+namespace PR5718 {
+ struct A { };
+
+ bool f(void (A::*f)(), void (A::*g)()) {
+ return f == g;
+ }
+}
+
+namespace BoolMemberPointer {
+ struct A { };
+
+ bool f(void (A::*f)()) {
+ return !f;
+ }
+
+ bool g(void (A::*f)()) {
+ if (!!f)
+ return true;
+ return false;
+ }
+}
+
+// PR5940
+namespace PR5940 {
+ class foo {
+ public:
+ virtual void baz(void);
+ };
+
+ void foo::baz(void) {
+ void (foo::*ptr)(void) = &foo::baz;
+ }
+}
+
+namespace MemberPointerImpCast {
+ struct A {
+ int x;
+ };
+ struct B : public A {
+ };
+ void f(B* obj, void (A::*method)()) {
+ (obj->*method)();
+ }
+}
+
+// PR6258
+namespace PR6258 {
+
+ struct A {
+ void f(bool);
+ };
+
+ void (A::*pf)(bool) = &A::f;
+
+ void f() {
+ void (A::*pf)(bool) = &A::f;
+ }
+}
+
+// PR7027
+namespace PR7027 {
+ struct X { void test( ); };
+ void testX() { &X::test; }
+}
+
+namespace test7 {
+ struct A { void foo(); virtual void vfoo(); };
+ struct B { void foo(); virtual void vfoo(); };
+ struct C : A, B { void foo(); virtual void vfoo(); };
+
+ // GLOBAL-ARM: @_ZN5test74ptr0E = global {{.*}} { i32 ptrtoint ({{.*}}* @_ZN5test71A3fooEv to i32), i32 0 }
+ // GLOBAL-ARM: @_ZN5test74ptr1E = global {{.*}} { i32 ptrtoint ({{.*}}* @_ZN5test71B3fooEv to i32), i32 8 }
+ // GLOBAL-ARM: @_ZN5test74ptr2E = global {{.*}} { i32 ptrtoint ({{.*}}* @_ZN5test71C3fooEv to i32), i32 0 }
+ // GLOBAL-ARM: @_ZN5test74ptr3E = global {{.*}} { i32 0, i32 1 }
+ // GLOBAL-ARM: @_ZN5test74ptr4E = global {{.*}} { i32 0, i32 9 }
+ // GLOBAL-ARM: @_ZN5test74ptr5E = global {{.*}} { i32 0, i32 1 }
+ void (C::*ptr0)() = &A::foo;
+ void (C::*ptr1)() = &B::foo;
+ void (C::*ptr2)() = &C::foo;
+ void (C::*ptr3)() = &A::vfoo;
+ void (C::*ptr4)() = &B::vfoo;
+ void (C::*ptr5)() = &C::vfoo;
+}
+
+namespace test8 {
+ struct X { };
+ typedef int (X::*pmf)(int);
+
+ // CHECK: {{define.*_ZN5test81fEv}}
+ pmf f() {
+ // CHECK: {{ret.*zeroinitializer}}
+ return pmf();
+ }
+}
+
+namespace test9 {
+ struct A {
+ void foo();
+ };
+ struct B : A {
+ void foo();
+ };
+
+ typedef void (A::*fooptr)();
+
+ struct S {
+ fooptr p;
+ };
+
+ // CODE-LP64-LABEL: define void @_ZN5test94testEv(
+ // CODE-LP64: alloca i32
+ // CODE-LP64-NEXT: ret void
+ void test() {
+ int x;
+ static S array[] = { (fooptr) &B::foo };
+ }
+}
+
+// rdar://problem/10815683 - Verify that we can emit reinterprets of
+// member pointers as constant initializers. For added trickiness,
+// we also add some non-trivial adjustments.
+namespace test10 {
+ struct A {
+ int nonEmpty;
+ void foo();
+ };
+ struct B : public A {
+ virtual void requireNonZeroAdjustment();
+ };
+ struct C {
+ int nonEmpty;
+ };
+ struct D : public C {
+ virtual void requireNonZeroAdjustment();
+ };
+
+
+// It's not that the offsets are doubled on ARM, it's that they're left-shifted by 1.
+
+// GLOBAL-LP64: @_ZN6test101aE = global { i64, i64 } { i64 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i64), i64 0 }, align 8
+// GLOBAL-LP32: @_ZN6test101aE = global { i32, i32 } { i32 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i32), i32 0 }, align 4
+// GLOBAL-ARM: @_ZN6test101aE = global { i32, i32 } { i32 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i32), i32 0 }, align 4
+ void (A::*a)() = &A::foo;
+
+// GLOBAL-LP64: @_ZN6test101bE = global { i64, i64 } { i64 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i64), i64 8 }, align 8
+// GLOBAL-LP32: @_ZN6test101bE = global { i32, i32 } { i32 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i32), i32 4 }, align 4
+// GLOBAL-ARM: @_ZN6test101bE = global { i32, i32 } { i32 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i32), i32 8 }, align 4
+ void (B::*b)() = (void (B::*)()) &A::foo;
+
+// GLOBAL-LP64: @_ZN6test101cE = global { i64, i64 } { i64 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i64), i64 8 }, align 8
+// GLOBAL-LP32: @_ZN6test101cE = global { i32, i32 } { i32 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i32), i32 4 }, align 4
+// GLOBAL-ARM: @_ZN6test101cE = global { i32, i32 } { i32 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i32), i32 8 }, align 4
+ void (C::*c)() = (void (C::*)()) (void (B::*)()) &A::foo;
+
+// GLOBAL-LP64: @_ZN6test101dE = global { i64, i64 } { i64 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i64), i64 16 }, align 8
+// GLOBAL-LP32: @_ZN6test101dE = global { i32, i32 } { i32 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i32), i32 8 }, align 4
+// GLOBAL-ARM: @_ZN6test101dE = global { i32, i32 } { i32 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i32), i32 16 }, align 4
+ void (D::*d)() = (void (C::*)()) (void (B::*)()) &A::foo;
+}
+
+namespace test11 {
+ struct A { virtual void a(); };
+ struct B : A {};
+ struct C : B { virtual void a(); };
+ void (C::*x)() = &C::a;
+
+ // GLOBAL-LP64: @_ZN6test111xE = global { i64, i64 } { i64 1, i64 0 }
+ // GLOBAL-LP32: @_ZN6test111xE = global { i32, i32 } { i32 1, i32 0 }
+ // GLOBAL-ARM: @_ZN6test111xE = global { i32, i32 } { i32 0, i32 1 }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/member-functions.cpp b/src/llvm-project/clang/test/CodeGenCXX/member-functions.cpp
new file mode 100644
index 0000000..58f709c
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/member-functions.cpp
@@ -0,0 +1,84 @@
+// RUN: %clang_cc1 -emit-llvm -triple x86_64-apple-darwin9 -o - %s | FileCheck %s
+
+struct C {
+ void f();
+ void g(int, ...);
+};
+
+// CHECK-LABEL: define void @_ZN1C1fEv
+void C::f() {
+}
+
+// CHECK-LABEL: define void @_Z5test1v
+void test1() {
+ C c;
+
+ // CHECK: call void @_ZN1C1fEv
+ c.f();
+
+ // CHECK: call void (%struct.C*, i32, ...) @_ZN1C1gEiz
+ c.g(1, 2, 3);
+}
+
+
+struct S {
+ inline S() { }
+ inline ~S() { }
+
+ void f_inline1() { }
+ inline void f_inline2() { }
+
+ static void g() { }
+ static void f();
+
+ virtual void v() {}
+};
+
+// CHECK-LABEL: define void @_ZN1S1fEv
+void S::f() {
+}
+
+void test2() {
+ S s;
+
+ s.f_inline1();
+ s.f_inline2();
+
+ S::g();
+}
+
+// S::S()
+// CHECK: define linkonce_odr void @_ZN1SC1Ev{{.*}} unnamed_addr
+
+// S::f_inline1()
+// CHECK-LABEL: define linkonce_odr void @_ZN1S9f_inline1Ev
+
+// S::f_inline2()
+// CHECK-LABEL: define linkonce_odr void @_ZN1S9f_inline2Ev
+
+// S::g()
+// CHECK-LABEL: define linkonce_odr void @_ZN1S1gEv
+
+// S::~S()
+// CHECK: define linkonce_odr void @_ZN1SD1Ev{{.*}} unnamed_addr
+
+struct T {
+ T operator+(const T&);
+};
+
+// CHECK-LABEL: define void @_Z5test3v
+void test3() {
+ T t1, t2;
+
+ // CHECK: call void @_ZN1TplERKS_
+ T result = t1 + t2;
+}
+
+// S::S()
+// CHECK: define linkonce_odr void @_ZN1SC2Ev{{.*}} unnamed_addr
+
+// S::v()
+// CHECK: define linkonce_odr void @_ZN1S1vEv{{.*}}unnamed_addr
+
+// S::~S()
+// CHECK: define linkonce_odr void @_ZN1SD2Ev{{.*}} unnamed_addr
diff --git a/src/llvm-project/clang/test/CodeGenCXX/member-init-anon-union.cpp b/src/llvm-project/clang/test/CodeGenCXX/member-init-anon-union.cpp
new file mode 100644
index 0000000..6c2f90d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/member-init-anon-union.cpp
@@ -0,0 +1,65 @@
+// RUN: %clang_cc1 %s -std=c++11 -triple x86_64-linux-gnu -emit-llvm -o - | FileCheck %s
+
+// PR10531.
+
+int make_a();
+
+static union {
+ int a = make_a();
+ char *b;
+};
+
+int f() { return a; }
+
+// CHECK-LABEL: define internal void @__cxx_global_var_init
+// CHECK-NOT: }
+// CHECK: call {{.*}}@"[[CONSTRUCT_GLOBAL:.*]]C1Ev"
+
+
+int g() {
+ union {
+ int a;
+ int b = 81;
+ };
+ // CHECK-LABEL: define {{.*}}_Z1gv
+ // CHECK-NOT: }
+ // CHECK: call {{.*}}@"[[CONSTRUCT_LOCAL:.*]]C1Ev"
+ return b;
+}
+
+struct A {
+ A();
+};
+union B {
+ int k;
+ struct {
+ A x;
+ int y = 123;
+ };
+ B() {}
+ B(int n) : k(n) {}
+};
+
+B b1;
+B b2(0);
+
+// CHECK: define {{.*}}@"[[CONSTRUCT_GLOBAL]]C2Ev"
+// CHECK-NOT: }
+// CHECK: call {{.*}}@_Z6make_a
+
+// CHECK: define {{.*}}@"[[CONSTRUCT_LOCAL]]C2Ev"
+// CHECK-NOT: }
+// CHECK: store i32 81
+
+// CHECK-LABEL: define {{.*}} @_ZN1BC2Ev(
+// CHECK: call void @_ZN1AC1Ev(
+// CHECK: store i32 123,
+// CHECK: }
+
+// CHECK-LABEL: define {{.*}} @_ZN1BC2Ei(
+// CHECK-NOT: call void @_ZN1AC1Ev(
+// CHECK-NOT: store i32 123,
+// CHECK: store i32 %
+// CHECK-NOT: call void @_ZN1AC1Ev(
+// CHECK-NOT: store i32 123,
+// CHECK: }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/member-init-assignment.cpp b/src/llvm-project/clang/test/CodeGenCXX/member-init-assignment.cpp
new file mode 100644
index 0000000..acc70846
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/member-init-assignment.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 %s -triple i386-unknown-unknown -emit-llvm -o - | FileCheck %s
+// PR7291
+
+struct Foo {
+ unsigned file_id;
+
+ Foo(unsigned arg);
+};
+
+Foo::Foo(unsigned arg) : file_id(arg = 42)
+{ }
+
+// CHECK: define {{.*}} @_ZN3FooC2Ej(%struct.Foo* %this, i32 %arg) unnamed_addr
+// CHECK: [[ARG:%.*]] = alloca i32
+// CHECK: store i32 42, i32* [[ARG]]
+// CHECK: store i32 42, i32* %{{.*}}
+// CHECK: ret {{void|%struct.Foo}}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/member-init-struct.cpp b/src/llvm-project/clang/test/CodeGenCXX/member-init-struct.cpp
new file mode 100644
index 0000000..d509b0e
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/member-init-struct.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 %s -emit-llvm-only -verify
+// expected-no-diagnostics
+
+struct A {int a;};
+struct B {float a;};
+struct C {
+ union {
+ A a;
+ B b[10];
+ };
+ _Complex float c;
+ int d[10];
+ void (C::*e)();
+ C() : a(), c(), d(), e() {}
+ C(A x) : a(x) {}
+ C(void (C::*x)(), int y) : b(), c(y), e(x) {}
+};
+A x;
+C a, b(x), c(0, 2);
diff --git a/src/llvm-project/clang/test/CodeGenCXX/member-init-union.cpp b/src/llvm-project/clang/test/CodeGenCXX/member-init-union.cpp
new file mode 100644
index 0000000..be171a3
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/member-init-union.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 %s -emit-llvm-only -verify
+// expected-no-diagnostics
+
+union x {
+ int a;
+ float b;
+ x(float y) : b(y) {}
+ x(int y) : a(y) {}
+};
+x a(1), b(1.0f);
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/member-templates.cpp b/src/llvm-project/clang/test/CodeGenCXX/member-templates.cpp
new file mode 100644
index 0000000..93d36ff
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/member-templates.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+// CHECK: ; ModuleID
+struct A {
+ template<typename T>
+ A(T);
+};
+
+template<typename T> A::A(T) {}
+
+struct B {
+ template<typename T>
+ B(T);
+};
+
+template<typename T> B::B(T) {}
+
+// CHECK-LABEL: define weak_odr void @_ZN1BC2IiEET_(%struct.B* %this, i32) unnamed_addr
+// CHECK-LABEL: define weak_odr void @_ZN1BC1IiEET_(%struct.B* %this, i32) unnamed_addr
+template B::B(int);
+
+template<typename T>
+struct C {
+ void f() {
+ int a[] = { 1, 2, 3 };
+ }
+};
+
+void f(C<int>& c) {
+ c.f();
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/merge-functions.cpp b/src/llvm-project/clang/test/CodeGenCXX/merge-functions.cpp
new file mode 100644
index 0000000..20a286e
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/merge-functions.cpp
@@ -0,0 +1,12 @@
+// REQUIRES: x86-registered-target
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -O1 -fmerge-functions -emit-llvm -o - -x c++ < %s | FileCheck %s -implicit-check-not=_ZN1A1gEiPi
+
+// Basic functionality test. Function merging doesn't kick in on functions that
+// are too simple.
+
+struct A {
+ virtual int f(int x, int *p) { return x ? *p : 1; }
+ virtual int g(int x, int *p) { return x ? *p : 1; }
+} a;
+
+// CHECK: define {{.*}} @_ZN1A1fEiPi
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-alignment-fail.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-alignment-fail.cpp
new file mode 100644
index 0000000..c8477f4
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-alignment-fail.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fno-rtti -emit-llvm -triple=i686-pc-win32 -o - %s 2>/dev/null | FileCheck %s
+// RUN: %clang_cc1 -fno-rtti -emit-llvm -triple=x86_64-pc-win32 -o - %s 2>/dev/null | FileCheck %s -check-prefix CHECK-X64
+
+struct B { char a; };
+struct A : virtual B {} a;
+
+// The <> indicate that the pointer is packed, which is required to support
+// microsoft layout in 32 bit mode, but not 64 bit mode.
+// CHECK: %struct.A = type <{ i32*, %struct.B }>
+// CHECK-X64: %struct.A = type { i32*, %struct.B }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-arg-order.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-arg-order.cpp
new file mode 100644
index 0000000..df945f9
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-arg-order.cpp
@@ -0,0 +1,76 @@
+// RUN: %clang_cc1 -mconstructor-aliases -std=c++11 -fexceptions -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s -check-prefix=X86
+// RUN: %clang_cc1 -mconstructor-aliases -std=c++11 -fexceptions -emit-llvm %s -o - -triple=x86_64-pc-win32 | FileCheck %s -check-prefix=X64
+
+struct A {
+ A(int a);
+ A(const A &o);
+ ~A();
+ int a;
+};
+
+void foo(A a, A b, A c) {
+}
+
+// Order of destruction should be left to right.
+//
+// X86-LABEL: define dso_local void @"?foo@@YAXUA@@00@Z"
+// X86: ([[argmem_ty:<{ %struct.A, %struct.A, %struct.A }>]]* inalloca)
+// X86: %[[a:[^ ]*]] = getelementptr inbounds [[argmem_ty]], [[argmem_ty]]* %0, i32 0, i32 0
+// X86: %[[b:[^ ]*]] = getelementptr inbounds [[argmem_ty]], [[argmem_ty]]* %0, i32 0, i32 1
+// X86: %[[c:[^ ]*]] = getelementptr inbounds [[argmem_ty]], [[argmem_ty]]* %0, i32 0, i32 2
+// X86: call x86_thiscallcc void @"??1A@@QAE@XZ"(%struct.A* %[[a]])
+// X86: call x86_thiscallcc void @"??1A@@QAE@XZ"(%struct.A* %[[b]])
+// X86: call x86_thiscallcc void @"??1A@@QAE@XZ"(%struct.A* %[[c]])
+// X86: ret void
+
+// X64-LABEL: define dso_local void @"?foo@@YAXUA@@00@Z"
+// X64: (%struct.A* %[[a:[^,]*]], %struct.A* %[[b:[^,]*]], %struct.A* %[[c:[^)]*]])
+// X64: call void @"??1A@@QEAA@XZ"(%struct.A* %[[a]])
+// X64: call void @"??1A@@QEAA@XZ"(%struct.A* %[[b]])
+// X64: call void @"??1A@@QEAA@XZ"(%struct.A* %[[c]])
+// X64: ret void
+
+
+void call_foo() {
+ foo(A(1), A(2), A(3));
+}
+
+// Order of evaluation should be right to left, and we should clean up the right
+// things as we unwind.
+//
+// X86-LABEL: define dso_local void @"?call_foo@@YAXXZ"()
+// X86: call i8* @llvm.stacksave()
+// X86: %[[argmem:[^ ]*]] = alloca inalloca [[argmem_ty]]
+// X86: %[[arg3:[^ ]*]] = getelementptr inbounds [[argmem_ty]], [[argmem_ty]]* %[[argmem]], i32 0, i32 2
+// X86: call x86_thiscallcc %struct.A* @"??0A@@QAE@H@Z"(%struct.A* %[[arg3]], i32 3)
+// X86: %[[arg2:[^ ]*]] = getelementptr inbounds [[argmem_ty]], [[argmem_ty]]* %[[argmem]], i32 0, i32 1
+// X86: invoke x86_thiscallcc %struct.A* @"??0A@@QAE@H@Z"(%struct.A* %[[arg2]], i32 2)
+// X86: %[[arg1:[^ ]*]] = getelementptr inbounds [[argmem_ty]], [[argmem_ty]]* %[[argmem]], i32 0, i32 0
+// X86: invoke x86_thiscallcc %struct.A* @"??0A@@QAE@H@Z"(%struct.A* %[[arg1]], i32 1)
+// X86: call void @"?foo@@YAXUA@@00@Z"([[argmem_ty]]* inalloca %[[argmem]])
+// X86: call void @llvm.stackrestore
+// X86: ret void
+//
+// lpad2:
+// X86: cleanuppad within none []
+// X86: call x86_thiscallcc void @"??1A@@QAE@XZ"(%struct.A* %[[arg2]])
+// X86: cleanupret
+//
+// ehcleanup:
+// X86: call x86_thiscallcc void @"??1A@@QAE@XZ"(%struct.A* %[[arg3]])
+
+// X64-LABEL: define dso_local void @"?call_foo@@YAXXZ"()
+// X64: call %struct.A* @"??0A@@QEAA@H@Z"(%struct.A* %[[arg3:[^,]*]], i32 3)
+// X64: invoke %struct.A* @"??0A@@QEAA@H@Z"(%struct.A* %[[arg2:[^,]*]], i32 2)
+// X64: invoke %struct.A* @"??0A@@QEAA@H@Z"(%struct.A* %[[arg1:[^,]*]], i32 1)
+// X64: call void @"?foo@@YAXUA@@00@Z"
+// X64: (%struct.A* %[[arg1]], %struct.A* %[[arg2]], %struct.A* %[[arg3]])
+// X64: ret void
+//
+// lpad2:
+// X64: cleanuppad within none []
+// X64: call void @"??1A@@QEAA@XZ"(%struct.A* %[[arg2]])
+// X64: cleanupret
+//
+// ehcleanup:
+// X64: call void @"??1A@@QEAA@XZ"(%struct.A* %[[arg3]])
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-array-cookies.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-array-cookies.cpp
new file mode 100644
index 0000000..2814045
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-array-cookies.cpp
@@ -0,0 +1,71 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
+
+struct ClassWithoutDtor {
+ char x;
+};
+
+void check_array_no_cookies() {
+// CHECK: define dso_local void @"?check_array_no_cookies@@YAXXZ"() [[NUW:#[0-9]+]]
+
+// CHECK: call i8* @"??_U@YAPAXI@Z"(i32 42)
+ ClassWithoutDtor *array = new ClassWithoutDtor[42];
+
+// CHECK: call void @"??_V@YAXPAX@Z"(
+ delete [] array;
+
+}
+
+struct ClassWithDtor {
+ char x;
+ ~ClassWithDtor() {}
+};
+
+void check_array_cookies_simple() {
+// CHECK: define {{.*}} @"?check_array_cookies_simple@@YAXXZ"()
+
+ ClassWithDtor *array = new ClassWithDtor[42];
+// CHECK: [[ALLOCATED:%.*]] = call i8* @"??_U@YAPAXI@Z"(i32 46)
+// 46 = 42 + size of cookie (4)
+// CHECK: [[COOKIE:%.*]] = bitcast i8* [[ALLOCATED]] to i32*
+// CHECK: store i32 42, i32* [[COOKIE]]
+// CHECK: [[ARRAY:%.*]] = getelementptr inbounds i8, i8* [[ALLOCATED]], i32 4
+// CHECK: bitcast i8* [[ARRAY]] to [[CLASS:%.*]]*
+
+ delete [] array;
+// CHECK: [[ARRAY_AS_CHAR:%.*]] = bitcast [[CLASS]]* {{%.*}} to i8*
+// CHECK: getelementptr inbounds i8, i8* [[ARRAY_AS_CHAR]], i32 -4
+}
+
+struct __attribute__((aligned(8))) ClassWithAlignment {
+ // FIXME: replace __attribute__((aligned(8))) with __declspec(align(8)) once
+ // http://llvm.org/bugs/show_bug.cgi?id=12631 is fixed.
+ int *x, *y;
+ ~ClassWithAlignment() {}
+};
+
+void check_array_cookies_aligned() {
+// CHECK: define {{.*}} @"?check_array_cookies_aligned@@YAXXZ"()
+ ClassWithAlignment *array = new ClassWithAlignment[42];
+// CHECK: [[ALLOCATED:%.*]] = call i8* @"??_U@YAPAXI@Z"(i32 344)
+// 344 = 42*8 + size of cookie (8, due to alignment)
+// CHECK: [[COOKIE:%.*]] = bitcast i8* [[ALLOCATED]] to i32*
+// CHECK: store i32 42, i32* [[COOKIE]]
+// CHECK: [[ARRAY:%.*]] = getelementptr inbounds i8, i8* [[ALLOCATED]], i32 8
+// CHECK: bitcast i8* [[ARRAY]] to [[CLASS:%.*]]*
+
+ delete [] array;
+// CHECK: [[ARRAY_AS_CHAR:%.*]] = bitcast [[CLASS]]*
+// CHECK: getelementptr inbounds i8, i8* [[ARRAY_AS_CHAR]], i32 -8
+}
+
+namespace PR23990 {
+struct S {
+ char x[42];
+ void operator delete[](void *p, __SIZE_TYPE__);
+ // CHECK-LABEL: define dso_local void @"?delete_s@PR23990@@YAXPAUS@1@@Z"(
+ // CHECK: call void @"??_VS@PR23990@@SAXPAXI@Z"(i8* {{.*}}, i32 42)
+};
+void delete_s(S *s) { delete[] s; }
+}
+
+// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-byval-sret.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-byval-sret.cpp
new file mode 100644
index 0000000..cbedec6
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-byval-sret.cpp
@@ -0,0 +1,70 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i686-pc-win32 -mconstructor-aliases -fno-rtti | FileCheck %s
+
+struct A {
+ A() : a(42) {}
+ A(const A &o) : a(o.a) {}
+ ~A() {}
+ int a;
+};
+
+struct B {
+ A foo(A o);
+ A __cdecl bar(A o);
+ A __stdcall baz(A o);
+ A __fastcall qux(A o);
+};
+
+A B::foo(A x) {
+ return x;
+}
+
+// CHECK-LABEL: define dso_local x86_thiscallcc %struct.A* @"?foo@B@@QAE?AUA@@U2@@Z"
+// CHECK: (%struct.B* %this, <{ %struct.A*, %struct.A }>* inalloca)
+// CHECK: getelementptr inbounds <{ %struct.A*, %struct.A }>, <{ %struct.A*, %struct.A }>* %{{.*}}, i32 0, i32 0
+// CHECK: load %struct.A*, %struct.A**
+// CHECK: ret %struct.A*
+
+A B::bar(A x) {
+ return x;
+}
+
+// CHECK-LABEL: define dso_local %struct.A* @"?bar@B@@QAA?AUA@@U2@@Z"
+// CHECK: (<{ %struct.B*, %struct.A*, %struct.A }>* inalloca)
+// CHECK: getelementptr inbounds <{ %struct.B*, %struct.A*, %struct.A }>, <{ %struct.B*, %struct.A*, %struct.A }>* %{{.*}}, i32 0, i32 1
+// CHECK: load %struct.A*, %struct.A**
+// CHECK: ret %struct.A*
+
+A B::baz(A x) {
+ return x;
+}
+
+// CHECK-LABEL: define dso_local x86_stdcallcc %struct.A* @"?baz@B@@QAG?AUA@@U2@@Z"
+// CHECK: (<{ %struct.B*, %struct.A*, %struct.A }>* inalloca)
+// CHECK: getelementptr inbounds <{ %struct.B*, %struct.A*, %struct.A }>, <{ %struct.B*, %struct.A*, %struct.A }>* %{{.*}}, i32 0, i32 1
+// CHECK: load %struct.A*, %struct.A**
+// CHECK: ret %struct.A*
+
+A B::qux(A x) {
+ return x;
+}
+
+// CHECK-LABEL: define dso_local x86_fastcallcc void @"?qux@B@@QAI?AUA@@U2@@Z"
+// CHECK: (%struct.B* inreg %this, %struct.A* inreg noalias sret %agg.result, <{ %struct.A }>* inalloca)
+// CHECK: ret void
+
+int main() {
+ B b;
+ A a = b.foo(A());
+ a = b.bar(a);
+ a = b.baz(a);
+ a = b.qux(a);
+}
+
+// CHECK: call x86_thiscallcc %struct.A* @"?foo@B@@QAE?AUA@@U2@@Z"
+// CHECK: (%struct.B* %{{[^,]*}}, <{ %struct.A*, %struct.A }>* inalloca %{{[^,]*}})
+// CHECK: call %struct.A* @"?bar@B@@QAA?AUA@@U2@@Z"
+// CHECK: (<{ %struct.B*, %struct.A*, %struct.A }>* inalloca %{{[^,]*}})
+// CHECK: call x86_stdcallcc %struct.A* @"?baz@B@@QAG?AUA@@U2@@Z"
+// CHECK: (<{ %struct.B*, %struct.A*, %struct.A }>* inalloca %{{[^,]*}})
+// CHECK: call x86_fastcallcc void @"?qux@B@@QAI?AUA@@U2@@Z"
+// CHECK: (%struct.B* inreg %{{[^,]*}}, %struct.A* inreg sret %{{.*}}, <{ %struct.A }>* inalloca %{{[^,]*}})
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-byval-thunks.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-byval-thunks.cpp
new file mode 100644
index 0000000..45dd4d0
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-byval-thunks.cpp
@@ -0,0 +1,113 @@
+// RUN: %clang_cc1 %s -fno-rtti -triple=i686-pc-win32 -emit-llvm -o - | FileCheck --check-prefix=CHECK32 %s
+// RUN: %clang_cc1 %s -fno-rtti -triple=x86_64-pc-win32 -emit-llvm -o - | FileCheck --check-prefix=CHECK64 %s
+
+namespace byval_thunk {
+struct Agg {
+ Agg();
+ Agg(const Agg &);
+ ~Agg();
+ int x;
+};
+
+struct A { virtual void foo(Agg x); };
+struct B { virtual void foo(Agg x); };
+struct C : A, B { C(); virtual void foo(Agg x); };
+C::C() {} // force emission
+
+// CHECK32-LABEL: define linkonce_odr dso_local x86_thiscallcc void @"?foo@C@byval_thunk@@W3AEXUAgg@2@@Z"
+// CHECK32: (%"struct.byval_thunk::C"* %this, <{ %"struct.byval_thunk::Agg" }>* inalloca)
+// CHECK32: getelementptr i8, i8* %{{.*}}, i32 -4
+// CHECK32: musttail call x86_thiscallcc void @"?foo@C@byval_thunk@@UAEXUAgg@2@@Z"
+// CHECK32: (%"struct.byval_thunk::C"* %{{.*}}, <{ %"struct.byval_thunk::Agg" }>* inalloca %0)
+// CHECK32-NEXT: ret void
+
+// CHECK64-LABEL: define linkonce_odr dso_local void @"?foo@C@byval_thunk@@W7EAAXUAgg@2@@Z"
+// CHECK64: (%"struct.byval_thunk::C"* %this, %"struct.byval_thunk::Agg"* %x)
+// CHECK64: getelementptr i8, i8* %{{.*}}, i32 -8
+// CHECK64: call void @"?foo@C@byval_thunk@@UEAAXUAgg@2@@Z"
+// CHECK64: (%"struct.byval_thunk::C"* %{{.*}}, %"struct.byval_thunk::Agg"* %x)
+// CHECK64-NOT: call
+// CHECK64: ret void
+}
+
+namespace stdcall_thunk {
+struct Agg {
+ Agg();
+ Agg(const Agg &);
+ ~Agg();
+ int x;
+};
+
+struct A { virtual void __stdcall foo(Agg x); };
+struct B { virtual void __stdcall foo(Agg x); };
+struct C : A, B { C(); virtual void __stdcall foo(Agg x); };
+C::C() {} // force emission
+
+// CHECK32-LABEL: define linkonce_odr dso_local x86_stdcallcc void @"?foo@C@stdcall_thunk@@W3AGXUAgg@2@@Z"
+// CHECK32: (<{ %"struct.stdcall_thunk::C"*, %"struct.stdcall_thunk::Agg" }>* inalloca)
+// CHECK32: %[[this_slot:[^ ]*]] = getelementptr inbounds <{ %"struct.stdcall_thunk::C"*, %"struct.stdcall_thunk::Agg" }>, <{ %"struct.stdcall_thunk::C"*, %"struct.stdcall_thunk::Agg" }>* %0, i32 0, i32 0
+// CHECK32: load %"struct.stdcall_thunk::C"*, %"struct.stdcall_thunk::C"** %[[this_slot]]
+// CHECK32: getelementptr i8, i8* %{{.*}}, i32 -4
+// CHECK32: store %"struct.stdcall_thunk::C"* %{{.*}}, %"struct.stdcall_thunk::C"** %[[this_slot]]
+// CHECK32: musttail call x86_stdcallcc void @"?foo@C@stdcall_thunk@@UAGXUAgg@2@@Z"
+// CHECK32: (<{ %"struct.stdcall_thunk::C"*, %"struct.stdcall_thunk::Agg" }>* inalloca %0)
+// CHECK32-NEXT: ret void
+
+// CHECK64-LABEL: define linkonce_odr dso_local void @"?foo@C@stdcall_thunk@@W7EAAXUAgg@2@@Z"
+// CHECK64: (%"struct.stdcall_thunk::C"* %this, %"struct.stdcall_thunk::Agg"* %x)
+// CHECK64: getelementptr i8, i8* %{{.*}}, i32 -8
+// CHECK64: call void @"?foo@C@stdcall_thunk@@UEAAXUAgg@2@@Z"
+// CHECK64: (%"struct.stdcall_thunk::C"* %{{.*}}, %"struct.stdcall_thunk::Agg"* %x)
+// CHECK64-NOT: call
+// CHECK64: ret void
+}
+
+namespace sret_thunk {
+struct Agg {
+ Agg();
+ Agg(const Agg &);
+ ~Agg();
+ int x;
+};
+
+struct A { virtual Agg __cdecl foo(Agg x); };
+struct B { virtual Agg __cdecl foo(Agg x); };
+struct C : A, B { C(); virtual Agg __cdecl foo(Agg x); };
+C::C() {} // force emission
+
+// CHECK32-LABEL: define linkonce_odr dso_local %"struct.sret_thunk::Agg"* @"?foo@C@sret_thunk@@W3AA?AUAgg@2@U32@@Z"
+// CHECK32: (<{ %"struct.sret_thunk::C"*, %"struct.sret_thunk::Agg"*, %"struct.sret_thunk::Agg" }>* inalloca)
+// CHECK32: %[[this_slot:[^ ]*]] = getelementptr inbounds <{ %"struct.sret_thunk::C"*, %"struct.sret_thunk::Agg"*, %"struct.sret_thunk::Agg" }>, <{ %"struct.sret_thunk::C"*, %"struct.sret_thunk::Agg"*, %"struct.sret_thunk::Agg" }>* %0, i32 0, i32 0
+// CHECK32: load %"struct.sret_thunk::C"*, %"struct.sret_thunk::C"** %[[this_slot]]
+// CHECK32: getelementptr i8, i8* %{{.*}}, i32 -4
+// CHECK32: store %"struct.sret_thunk::C"* %{{.*}}, %"struct.sret_thunk::C"** %[[this_slot]]
+// CHECK32: %[[rv:[^ ]*]] = musttail call %"struct.sret_thunk::Agg"* @"?foo@C@sret_thunk@@UAA?AUAgg@2@U32@@Z"
+// CHECK32: (<{ %"struct.sret_thunk::C"*, %"struct.sret_thunk::Agg"*, %"struct.sret_thunk::Agg" }>* inalloca %0)
+// CHECK32-NEXT: ret %"struct.sret_thunk::Agg"* %[[rv]]
+
+// CHECK64-LABEL: define linkonce_odr dso_local void @"?foo@C@sret_thunk@@W7EAA?AUAgg@2@U32@@Z"
+// CHECK64: (%"struct.sret_thunk::C"* %this, %"struct.sret_thunk::Agg"* noalias sret %agg.result, %"struct.sret_thunk::Agg"* %x)
+// CHECK64: getelementptr i8, i8* %{{.*}}, i32 -8
+// CHECK64: call void @"?foo@C@sret_thunk@@UEAA?AUAgg@2@U32@@Z"
+// CHECK64: (%"struct.sret_thunk::C"* %{{.*}}, %"struct.sret_thunk::Agg"* sret %agg.result, %"struct.sret_thunk::Agg"* %x)
+// CHECK64-NOT: call
+// CHECK64: ret void
+}
+
+#if 0
+// FIXME: When we extend LLVM IR to allow forwarding of varargs through musttail
+// calls, use this test.
+namespace variadic_thunk {
+struct Agg {
+ Agg();
+ Agg(const Agg &);
+ ~Agg();
+ int x;
+};
+
+struct A { virtual void foo(Agg x, ...); };
+struct B { virtual void foo(Agg x, ...); };
+struct C : A, B { C(); virtual void foo(Agg x, ...); };
+C::C() {} // force emission
+}
+#endif
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-byval-vararg.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-byval-vararg.cpp
new file mode 100644
index 0000000..e6a36e2
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-byval-vararg.cpp
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -Wno-non-pod-varargs -emit-llvm %s -o - -triple=i686-pc-win32 -mconstructor-aliases -fno-rtti | FileCheck %s
+
+#include <stdarg.h>
+
+struct A {
+ A(int a) : a(a) {}
+ A(const A &o) : a(o.a) {}
+ ~A() {}
+ int a;
+};
+
+int foo(A a, ...) {
+ va_list ap;
+ va_start(ap, a);
+ int sum = 0;
+ for (int i = 0; i < a.a; ++i)
+ sum += va_arg(ap, int);
+ va_end(ap);
+ return sum;
+}
+
+// CHECK-LABEL: define dso_local i32 @"?foo@@YAHUA@@ZZ"(<{ %struct.A }>* inalloca, ...)
+
+int main() {
+ return foo(A(3), 1, 2, 3);
+}
+// CHECK-LABEL: define dso_local i32 @main()
+// CHECK: %[[argmem:[^ ]*]] = alloca inalloca <{ %struct.A, i32, i32, i32 }>
+// CHECK: call i32 {{.*bitcast.*}}@"?foo@@YAHUA@@ZZ"{{.*}}(<{ %struct.A, i32, i32, i32 }>* inalloca %[[argmem]])
+
+void varargs_zero(...);
+void varargs_one(int, ...);
+void varargs_two(int, int, ...);
+void varargs_three(int, int, int, ...);
+void call_var_args() {
+ A x(3);
+ varargs_zero(x);
+ varargs_one(1, x);
+ varargs_two(1, 2, x);
+ varargs_three(1, 2, 3, x);
+}
+
+// CHECK-LABEL: define dso_local void @"?call_var_args@@YAXXZ"()
+// CHECK: call void {{.*bitcast.*varargs_zero.*}}(<{ %struct.A }>* inalloca %{{.*}})
+// CHECK: call void {{.*bitcast.*varargs_one.*}}(<{ i32, %struct.A }>* inalloca %{{.*}})
+// CHECK: call void {{.*bitcast.*varargs_two.*}}(<{ i32, i32, %struct.A }>* inalloca %{{.*}})
+// CHECK: call void {{.*bitcast.*varargs_three.*}}(<{ i32, i32, i32, %struct.A }>* inalloca %{{.*}})
+
+// CHECK-LABEL: declare dso_local void @"?varargs_zero@@YAXZZ"(...)
+// CHECK-LABEL: declare dso_local void @"?varargs_one@@YAXHZZ"(i32, ...)
+// CHECK-LABEL: declare dso_local void @"?varargs_two@@YAXHHZZ"(i32, i32, ...)
+// CHECK-LABEL: declare dso_local void @"?varargs_three@@YAXHHHZZ"(i32, i32, i32, ...)
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-cdecl-method-sret.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-cdecl-method-sret.cpp
new file mode 100644
index 0000000..34e2bc5
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-cdecl-method-sret.cpp
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -triple i386-pc-win32 -emit-llvm %s -o - | FileCheck %s
+
+// PR15768
+
+// A trivial 20 byte struct is returned indirectly and taken as byval.
+struct S {
+ S();
+ int a, b, c, d, e;
+};
+
+struct C {
+ S variadic_sret(const char *f, ...);
+ S __cdecl cdecl_sret();
+ S __cdecl byval_and_sret(S a);
+ int c;
+};
+
+S C::variadic_sret(const char *f, ...) { return S(); }
+S C::cdecl_sret() { return S(); }
+S C::byval_and_sret(S a) { return S(); }
+
+// CHECK: define dso_local void @"?variadic_sret@C@@QAA?AUS@@PBDZZ"(%struct.C* %this, %struct.S* noalias sret %agg.result, i8* %f, ...)
+// CHECK: define dso_local void @"?cdecl_sret@C@@QAA?AUS@@XZ"(%struct.C* %this, %struct.S* noalias sret %agg.result)
+// CHECK: define dso_local void @"?byval_and_sret@C@@QAA?AUS@@U2@@Z"(%struct.C* %this, %struct.S* noalias sret %agg.result, %struct.S* byval align 4 %a)
+
+int main() {
+ C c;
+ c.variadic_sret("asdf");
+ c.cdecl_sret();
+ c.byval_and_sret(S());
+}
+// CHECK-LABEL: define dso_local i32 @main()
+// CHECK: call void {{.*}} @"?variadic_sret@C@@QAA?AUS@@PBDZZ"
+// CHECK: call void @"?cdecl_sret@C@@QAA?AUS@@XZ"
+// CHECK: call void @"?byval_and_sret@C@@QAA?AUS@@U2@@Z"
+
+// __fastcall has similar issues.
+struct A {
+ S __fastcall f(int x);
+};
+S A::f(int x) {
+ return S();
+}
+// CHECK-LABEL: define dso_local x86_fastcallcc void @"?f@A@@QAI?AUS@@H@Z"(%struct.A* inreg %this, %struct.S* inreg noalias sret %agg.result, i32 %x)
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-constexpr-vs-inheritance.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-constexpr-vs-inheritance.cpp
new file mode 100644
index 0000000..6f42603
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-constexpr-vs-inheritance.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -std=c++11 -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
+
+struct A {
+ constexpr A(int x) : x(x) {}
+ virtual void f();
+ int x;
+};
+
+A a(42);
+// CHECK: @"?a@@3UA@@A" = dso_local global { { [1 x i8*] }*, i32 } { { [1 x i8*] }* @"??_7A@@6B@", i32 42 }, align 4
+
+struct B {
+ constexpr B(int y) : y(y) {}
+ virtual void g();
+ int y;
+};
+
+struct C : A, B {
+ constexpr C() : A(777), B(13) {}
+};
+
+C c;
+// CHECK: @"?c@@3UC@@A" = dso_local global { { [1 x i8*] }*, i32, { [1 x i8*] }*, i32 } { { [1 x i8*] }* @"??_7C@@6BA@@@", i32 777, { [1 x i8*] }* @"??_7C@@6BB@@@", i32 13 }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-default-cc.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-default-cc.cpp
new file mode 100644
index 0000000..804ee51
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-default-cc.cpp
@@ -0,0 +1,56 @@
+// RUN: %clang_cc1 -triple i386-pc-linux -emit-llvm %s -o - | FileCheck -check-prefix GCABI %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -DMS_ABI -triple=i386-pc-win32 | FileCheck -check-prefix MSABI %s
+
+#ifdef MS_ABI
+# define METHOD_CC __thiscall
+#else
+# define METHOD_CC __attribute__ ((cdecl))
+#endif
+
+// Test that it's OK to have multiple function declarations with the default CC
+// both mentioned explicitly and implied.
+void foo();
+void __cdecl foo();
+void __cdecl foo() {}
+// GCABI-LABEL: define void @_Z3foov()
+// MSABI: define dso_local void @"?foo@@YAXXZ"
+
+void __cdecl bar();
+void bar();
+void bar() {}
+// GCABI-LABEL: define void @_Z3barv()
+// MSABI: define dso_local void @"?bar@@YAXXZ"
+
+// Test that it's OK to mark either the method declaration or method definition
+// with a default CC explicitly.
+class A {
+public:
+ void baz();
+ void METHOD_CC qux();
+
+ static void static_baz();
+ static void __cdecl static_qux();
+};
+
+void METHOD_CC A::baz() {}
+// GCABI-LABEL: define void @_ZN1A3bazEv
+// MSABI: define dso_local x86_thiscallcc void @"?baz@A@@QAEXXZ"
+void A::qux() {}
+// GCABI-LABEL: define void @_ZN1A3quxEv
+// MSABI: define dso_local x86_thiscallcc void @"?qux@A@@QAEXXZ"
+
+void __cdecl static_baz() {}
+// GCABI-LABEL: define void @_Z10static_bazv
+// MSABI: define dso_local void @"?static_baz@@YAXXZ"
+void static_qux() {}
+// GCABI-LABEL: define void @_Z10static_quxv
+// MSABI: define dso_local void @"?static_qux@@YAXXZ"
+
+namespace PR31656 {
+template <int I>
+void __cdecl callee(int args[I]);
+// GCABI-LABEL: declare void @_ZN7PR316566calleeILi1EEEvPi(
+// MSABI: declare dso_local void @"??$callee@$00@PR31656@@YAXQAH@Z"(
+
+void caller() { callee<1>(0); }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp
new file mode 100644
index 0000000..e45d372
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp
@@ -0,0 +1,143 @@
+// RUN: %clang_cc1 -emit-llvm -O1 -o - -fexceptions -triple=i386-pc-win32 %s | FileCheck %s
+
+struct S { char a; };
+struct V { virtual void f(); };
+struct A : virtual V {};
+struct B : S, virtual V {};
+struct T {};
+
+T* test0() { return dynamic_cast<T*>((B*)0); }
+// CHECK-LABEL: define dso_local noalias %struct.T* @"?test0@@YAPAUT@@XZ"()
+// CHECK: ret %struct.T* null
+
+T* test1(V* x) { return &dynamic_cast<T&>(*x); }
+// CHECK-LABEL: define dso_local %struct.T* @"?test1@@YAPAUT@@PAUV@@@Z"(%struct.V* %x)
+// CHECK: [[CAST:%.*]] = bitcast %struct.V* %x to i8*
+// CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[CAST]], i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUV@@@8" to i8*), i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUT@@@8" to i8*), i32 1)
+// CHECK-NEXT: [[RET:%.*]] = bitcast i8* [[CALL]] to %struct.T*
+// CHECK-NEXT: ret %struct.T* [[RET]]
+
+T* test2(A* x) { return &dynamic_cast<T&>(*x); }
+// CHECK-LABEL: define dso_local %struct.T* @"?test2@@YAPAUT@@PAUA@@@Z"(%struct.A* %x)
+// CHECK: [[CAST:%.*]] = bitcast %struct.A* %x to i8*
+// CHECK-NEXT: [[VBPTRPTR:%.*]] = getelementptr inbounds %struct.A, %struct.A* %x, i32 0, i32 0
+// CHECK-NEXT: [[VBTBL:%.*]] = load i32*, i32** [[VBPTRPTR]], align 4
+// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32, i32* [[VBTBL]], i32 1
+// CHECK-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4
+// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[CAST]], i32 [[VBOFFS]]
+// CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[ADJ]], i32 [[VBOFFS]], i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUA@@@8" to i8*), i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUT@@@8" to i8*), i32 1)
+// CHECK-NEXT: [[RET:%.*]] = bitcast i8* [[CALL]] to %struct.T*
+// CHECK-NEXT: ret %struct.T* [[RET]]
+
+T* test3(B* x) { return &dynamic_cast<T&>(*x); }
+// CHECK-LABEL: define dso_local %struct.T* @"?test3@@YAPAUT@@PAUB@@@Z"(%struct.B* %x)
+// CHECK: [[VOIDP:%.*]] = getelementptr inbounds %struct.B, %struct.B* %x, i32 0, i32 0, i32 0
+// CHECK-NEXT: [[VBPTR:%.*]] = getelementptr inbounds i8, i8* [[VOIDP]], i32 4
+// CHECK-NEXT: [[VBPTRPTR:%.*]] = bitcast i8* [[VBPTR:%.*]] to i32**
+// CHECK-NEXT: [[VBTBL:%.*]] = load i32*, i32** [[VBPTRPTR]], align 4
+// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32, i32* [[VBTBL]], i32 1
+// CHECK-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4
+// CHECK-NEXT: [[DELTA:%.*]] = add nsw i32 [[VBOFFS]], 4
+// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[VOIDP]], i32 [[DELTA]]
+// CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[ADJ]], i32 [[DELTA]], i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUB@@@8" to i8*), i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUT@@@8" to i8*), i32 1)
+// CHECK-NEXT: [[RET:%.*]] = bitcast i8* [[CALL]] to %struct.T*
+// CHECK-NEXT: ret %struct.T* [[RET]]
+
+T* test4(V* x) { return dynamic_cast<T*>(x); }
+// CHECK-LABEL: define dso_local %struct.T* @"?test4@@YAPAUT@@PAUV@@@Z"(%struct.V* %x)
+// CHECK: [[CAST:%.*]] = bitcast %struct.V* %x to i8*
+// CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[CAST]], i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUV@@@8" to i8*), i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUT@@@8" to i8*), i32 0)
+// CHECK-NEXT: [[RET:%.*]] = bitcast i8* [[CALL]] to %struct.T*
+// CHECK-NEXT: ret %struct.T* [[RET]]
+
+T* test5(A* x) { return dynamic_cast<T*>(x); }
+// CHECK-LABEL: define dso_local %struct.T* @"?test5@@YAPAUT@@PAUA@@@Z"(%struct.A* %x)
+// CHECK: [[CHECK:%.*]] = icmp eq %struct.A* %x, null
+// CHECK-NEXT: br i1 [[CHECK]]
+// CHECK: [[VOIDP:%.*]] = bitcast %struct.A* %x to i8*
+// CHECK-NEXT: [[VBPTRPTR:%.*]] = getelementptr inbounds %struct.A, %struct.A* %x, i32 0, i32 0
+// CHECK-NEXT: [[VBTBL:%.*]] = load i32*, i32** [[VBPTRPTR]], align 4
+// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32, i32* [[VBTBL]], i32 1
+// CHECK-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4
+// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[VOIDP]], i32 [[VBOFFS]]
+// CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[ADJ]], i32 [[VBOFFS]], i8* {{.*}}bitcast (%rtti.TypeDescriptor7* @"??_R0?AUA@@@8" to i8*), i8* {{.*}}bitcast (%rtti.TypeDescriptor7* @"??_R0?AUT@@@8" to i8*), i32 0)
+// CHECK-NEXT: [[RES:%.*]] = bitcast i8* [[CALL]] to %struct.T*
+// CHECK-NEXT: br label
+// CHECK: [[RET:%.*]] = phi %struct.T*
+// CHECK-NEXT: ret %struct.T* [[RET]]
+
+T* test6(B* x) { return dynamic_cast<T*>(x); }
+// CHECK-LABEL: define dso_local %struct.T* @"?test6@@YAPAUT@@PAUB@@@Z"(%struct.B* %x)
+// CHECK: [[CHECK:%.*]] = icmp eq %struct.B* %x, null
+// CHECK-NEXT: br i1 [[CHECK]]
+// CHECK: [[CAST:%.*]] = getelementptr inbounds %struct.B, %struct.B* %x, i32 0, i32 0, i32 0
+// CHECK-NEXT: [[VBPTR:%.*]] = getelementptr inbounds i8, i8* [[CAST]], i32 4
+// CHECK-NEXT: [[VBPTRPTR:%.*]] = bitcast i8* [[VBPTR]] to i32**
+// CHECK-NEXT: [[VBTBL:%.*]] = load i32*, i32** [[VBPTRPTR]], align 4
+// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32, i32* [[VBTBL]], i32 1
+// CHECK-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4
+// CHECK-NEXT: [[DELTA:%.*]] = add nsw i32 [[VBOFFS]], 4
+// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[CAST]], i32 [[DELTA]]
+// CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* nonnull [[ADJ]], i32 [[DELTA]], i8* {{.*}}bitcast (%rtti.TypeDescriptor7* @"??_R0?AUB@@@8" to i8*), i8* {{.*}}bitcast (%rtti.TypeDescriptor7* @"??_R0?AUT@@@8" to i8*), i32 0)
+// CHECK-NEXT: [[RES:%.*]] = bitcast i8* [[CALL]] to %struct.T*
+// CHECK-NEXT: br label
+// CHECK: [[RET:%.*]] = phi %struct.T*
+// CHECK-NEXT: ret %struct.T* [[RET]]
+
+void* test7(V* x) { return dynamic_cast<void*>(x); }
+// CHECK-LABEL: define dso_local i8* @"?test7@@YAPAXPAUV@@@Z"(%struct.V* %x)
+// CHECK: [[CAST:%.*]] = bitcast %struct.V* %x to i8*
+// CHECK-NEXT: [[RET:%.*]] = tail call i8* @__RTCastToVoid(i8* [[CAST]])
+// CHECK-NEXT: ret i8* [[RET]]
+
+void* test8(A* x) { return dynamic_cast<void*>(x); }
+// CHECK-LABEL: define dso_local i8* @"?test8@@YAPAXPAUA@@@Z"(%struct.A* %x)
+// CHECK: [[CHECK:%.*]] = icmp eq %struct.A* %x, null
+// CHECK-NEXT: br i1 [[CHECK]]
+// CHECK: [[VOIDP:%.*]] = bitcast %struct.A* %x to i8*
+// CHECK-NEXT: [[VBPTRPTR:%.*]] = getelementptr inbounds %struct.A, %struct.A* %x, i32 0, i32 0
+// CHECK-NEXT: [[VBTBL:%.*]] = load i32*, i32** [[VBPTRPTR]], align 4
+// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32, i32* [[VBTBL]], i32 1
+// CHECK-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4
+// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[VOIDP]], i32 [[VBOFFS]]
+// CHECK-NEXT: [[RES:%.*]] = tail call i8* @__RTCastToVoid(i8* [[ADJ]])
+// CHECK-NEXT: br label
+// CHECK: [[RET:%.*]] = phi i8*
+// CHECK-NEXT: ret i8* [[RET]]
+
+void* test9(B* x) { return dynamic_cast<void*>(x); }
+// CHECK-LABEL: define dso_local i8* @"?test9@@YAPAXPAUB@@@Z"(%struct.B* %x)
+// CHECK: [[CHECK:%.*]] = icmp eq %struct.B* %x, null
+// CHECK-NEXT: br i1 [[CHECK]]
+// CHECK: [[CAST:%.*]] = getelementptr inbounds %struct.B, %struct.B* %x, i32 0, i32 0, i32 0
+// CHECK-NEXT: [[VBPTR:%.*]] = getelementptr inbounds i8, i8* [[CAST]], i32 4
+// CHECK-NEXT: [[VBPTRPTR:%.*]] = bitcast i8* [[VBPTR]] to i32**
+// CHECK-NEXT: [[VBTBL:%.*]] = load i32*, i32** [[VBPTRPTR]], align 4
+// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32, i32* [[VBTBL]], i32 1
+// CHECK-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4
+// CHECK-NEXT: [[DELTA:%.*]] = add nsw i32 [[VBOFFS]], 4
+// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[CAST]], i32 [[DELTA]]
+// CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTCastToVoid(i8* nonnull [[ADJ]])
+// CHECK-NEXT: br label
+// CHECK: [[RET:%.*]] = phi i8*
+// CHECK-NEXT: ret i8* [[RET]]
+
+namespace PR25606 {
+struct Cleanup {
+ ~Cleanup();
+};
+struct S1 { virtual ~S1(); };
+struct S2 : virtual S1 {};
+struct S3 : S2 {};
+
+S3 *f(S2 &s) {
+ Cleanup c;
+ return dynamic_cast<S3 *>(&s);
+}
+// CHECK-LABEL: define dso_local %"struct.PR25606::S3"* @"?f@PR25606@@YAPAUS3@1@AAUS2@1@@Z"(
+// CHECK: [[CALL:%.*]] = invoke i8* @__RTDynamicCast
+
+// CHECK: [[BC:%.*]] = bitcast i8* [[CALL]] to %"struct.PR25606::S3"*
+// CHECK: call x86_thiscallcc void @"??1Cleanup@PR25606@@QAE@XZ"(
+// CHECK: ret %"struct.PR25606::S3"* [[BC]]
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-eh-catch.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-eh-catch.cpp
new file mode 100644
index 0000000..53f8717
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-eh-catch.cpp
@@ -0,0 +1,164 @@
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=x86_64-pc-windows-msvc \
+// RUN: -mconstructor-aliases -fexceptions -fcxx-exceptions \
+// RUN: -O1 -disable-llvm-passes \
+// RUN: | FileCheck -check-prefix WIN64 %s
+
+extern "C" void might_throw();
+
+// Simplify the generated IR with noexcept.
+extern "C" void recover() noexcept(true);
+extern "C" void handle_exception(void *e) noexcept(true);
+
+extern "C" void catch_all() {
+ try {
+ might_throw();
+ } catch (...) {
+ recover();
+ }
+}
+
+// WIN64-LABEL: define dso_local void @catch_all()
+// WIN64: invoke void @might_throw()
+// WIN64-NEXT: to label %[[cont:[^ ]*]] unwind label %[[catchswitch_lpad:[^ ]*]]
+//
+// WIN64: [[catchswitch_lpad]]
+// WIN64: %[[catchswitch:[^ ]*]] = catchswitch within none [label %[[catchpad_lpad:[^ ]*]]] unwind to caller
+//
+// WIN64: [[catchpad_lpad]]
+// WIN64: catchpad within %[[catchswitch]] [i8* null, i32 64, i8* null]
+// WIN64: call void @recover()
+// WIN64: catchret from %{{.*}} to label %[[catchret:[^ ]*]]
+//
+// WIN64: [[catchret]]
+// WIN64-NEXT: br label %[[ret:[^ ]*]]
+//
+// WIN64: [[ret]]
+// WIN64: ret void
+//
+// WIN64: [[cont]]
+// WIN64: br label %[[ret]]
+
+extern "C" void catch_int() {
+ try {
+ might_throw();
+ } catch (int e) {
+ handle_exception(&e);
+ }
+}
+
+// WIN64-LABEL: define dso_local void @catch_int()
+// WIN64: catchpad within %{{[^ ]*}} [%rtti.TypeDescriptor2* @"??_R0H@8", i32 0, i32* %[[e_addr:[^\]]*]]]
+//
+// The catchpad instruction starts the lifetime of 'e'. Unfortunately, that
+// leaves us with nowhere to put lifetime.start, so we don't emit lifetime
+// markers for now.
+// WIN64-NOT: lifetime.start
+//
+// WIN64: %[[e_i8:[^ ]*]] = bitcast i32* %[[e_addr]] to i8*
+// WIN64-NOT: lifetime.start
+// WIN64: call void @handle_exception
+// WIN64-SAME: (i8* %[[e_i8]])
+// WIN64-NOT: lifetime.end
+// WIN64: catchret
+
+extern "C" void catch_int_unnamed() {
+ try {
+ might_throw();
+ } catch (int) {
+ }
+}
+
+// WIN64-LABEL: define dso_local void @catch_int_unnamed()
+// WIN64: catchpad within %{{.*}} [%rtti.TypeDescriptor2* @"??_R0H@8", i32 0, i8* null]
+// WIN64: catchret
+
+struct A {
+ A();
+ A(const A &o);
+ ~A();
+ int a;
+};
+
+struct B : A {
+ B();
+ B(const B &o);
+ ~B();
+ int b;
+};
+
+extern "C" void catch_a_byval() {
+ try {
+ might_throw();
+ } catch (A e) {
+ handle_exception(&e);
+ }
+}
+
+// WIN64-LABEL: define dso_local void @catch_a_byval()
+// WIN64: %[[e_addr:[^ ]*]] = alloca %struct.A
+// WIN64: catchpad within %{{[^ ]*}} [%rtti.TypeDescriptor7* @"??_R0?AUA@@@8", i32 0, %struct.A* %[[e_addr]]]
+// WIN64: %[[e_i8:[^ ]*]] = bitcast %struct.A* %[[e_addr]] to i8*
+// WIN64: call void @handle_exception(i8* %[[e_i8]])
+// WIN64: catchret
+
+extern "C" void catch_a_ref() {
+ try {
+ might_throw();
+ } catch (A &e) {
+ handle_exception(&e);
+ }
+}
+
+// WIN64-LABEL: define dso_local void @catch_a_ref()
+// WIN64: %[[e_addr:[^ ]*]] = alloca %struct.A*
+// WIN64: catchpad within %{{[^ ]*}} [%rtti.TypeDescriptor7* @"??_R0?AUA@@@8", i32 8, %struct.A** %[[e_addr]]]
+// WIN64: %[[eptr:[^ ]*]] = load %struct.A*, %struct.A** %[[e_addr]]
+// WIN64: %[[eptr_i8:[^ ]*]] = bitcast %struct.A* %[[eptr]] to i8*
+// WIN64: call void @handle_exception(i8* %[[eptr_i8]])
+// WIN64: catchret
+
+extern "C" void fn_with_exc_spec() throw(int) {
+ might_throw();
+}
+
+// WIN64-LABEL: define dso_local void @fn_with_exc_spec()
+// WIN64: call void @might_throw()
+// WIN64-NEXT: ret void
+
+extern "C" void catch_nested() {
+ try {
+ might_throw();
+ } catch (int) {
+ try {
+ might_throw();
+ } catch (int) {
+ might_throw();
+ }
+ }
+}
+
+// WIN64-LABEL: define dso_local void @catch_nested()
+// WIN64: invoke void @might_throw()
+// WIN64-NEXT: to label %{{.*}} unwind label %[[catchswitch_outer:[^ ]*]]
+//
+// WIN64: [[catchswitch_outer]]
+// WIN64: %[[catchswitch_outer_scope:[^ ]*]] = catchswitch within none [label %[[catch_int_outer:[^ ]*]]] unwind to caller
+//
+// WIN64: [[catch_int_outer]]
+// WIN64: %[[catchpad:[^ ]*]] = catchpad within %[[catchswitch_outer_scope]] [%rtti.TypeDescriptor2* @"??_R0H@8", i32 0, i8* null]
+// WIN64: invoke void @might_throw()
+// WIN64-NEXT: to label %[[cont2:[^ ]*]] unwind label %[[catchswitch_inner:[^ ]*]]
+//
+// WIN64: [[catchswitch_inner]]
+// WIN64: %[[catchswitch_inner_scope:[^ ]*]] = catchswitch within %[[catchpad]] [label %[[catch_int_inner:[^ ]*]]] unwind to caller
+//
+// WIN64: [[catch_int_inner]]
+// WIN64: catchpad within %[[catchswitch_inner_scope]] [%rtti.TypeDescriptor2* @"??_R0H@8", i32 0, i8* null]
+// WIN64-NEXT: call void @might_throw()
+// WIN64: catchret {{.*}} to label %[[catchret2:[^ ]*]]
+//
+// WIN64: [[catchret2]]
+// WIN64: catchret {{.*}} to label %[[mainret:[^ ]*]]
+//
+// WIN64: [[mainret]]
+// WIN64: ret void
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp
new file mode 100644
index 0000000..6682faf
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp
@@ -0,0 +1,339 @@
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=i386-pc-win32 -mconstructor-aliases -fexceptions -fcxx-exceptions -fno-rtti | FileCheck -check-prefix WIN32 -check-prefix WIN32-O0 %s
+// RUN: %clang_cc1 -std=c++11 -emit-llvm -O3 -disable-llvm-passes %s -o - -triple=i386-pc-win32 -mconstructor-aliases -fexceptions -fcxx-exceptions -fno-rtti | FileCheck -check-prefix WIN32 -check-prefix WIN32-O3 -check-prefix WIN32-LIFETIME %s
+
+struct A {
+ A();
+ ~A();
+ int a;
+};
+
+A getA();
+
+int TakesTwo(A a, A b);
+void HasEHCleanup() {
+ TakesTwo(getA(), getA());
+}
+
+// With exceptions, we need to clean up at least one of these temporaries.
+// WIN32-LABEL: define dso_local void @"?HasEHCleanup@@YAXXZ"() {{.*}} {
+// WIN32: %[[base:.*]] = call i8* @llvm.stacksave()
+// If this call throws, we have to restore the stack.
+// WIN32: call void @"?getA@@YA?AUA@@XZ"(%struct.A* sret %{{.*}})
+// If this call throws, we have to cleanup the first temporary.
+// WIN32: invoke void @"?getA@@YA?AUA@@XZ"(%struct.A* sret %{{.*}})
+// If this call throws, we have to cleanup the stacksave.
+// WIN32: call i32 @"?TakesTwo@@YAHUA@@0@Z"
+// WIN32: call void @llvm.stackrestore
+// WIN32: ret void
+//
+// There should be one dtor call for unwinding from the second getA.
+// WIN32: cleanuppad
+// WIN32: call x86_thiscallcc void @"??1A@@QAE@XZ"({{.*}})
+// WIN32-NOT: @"??1A@@QAE@XZ"
+// WIN32: }
+
+void TakeRef(const A &a);
+int HasDeactivatedCleanups() {
+ return TakesTwo((TakeRef(A()), A()), (TakeRef(A()), A()));
+}
+
+// WIN32-LABEL: define dso_local i32 @"?HasDeactivatedCleanups@@YAHXZ"() {{.*}} {
+// WIN32: %[[isactive:.*]] = alloca i1
+// WIN32: call i8* @llvm.stacksave()
+// WIN32: %[[argmem:.*]] = alloca inalloca [[argmem_ty:<{ %struct.A, %struct.A }>]]
+// WIN32: %[[arg1:.*]] = getelementptr inbounds [[argmem_ty]], [[argmem_ty]]* %[[argmem]], i32 0, i32 1
+// WIN32: call x86_thiscallcc %struct.A* @"??0A@@QAE@XZ"
+// WIN32: invoke void @"?TakeRef@@YAXABUA@@@Z"
+//
+// WIN32: invoke x86_thiscallcc %struct.A* @"??0A@@QAE@XZ"(%struct.A* %[[arg1]])
+// WIN32: store i1 true, i1* %[[isactive]]
+//
+// WIN32: %[[arg0:.*]] = getelementptr inbounds [[argmem_ty]], [[argmem_ty]]* %[[argmem]], i32 0, i32 0
+// WIN32: invoke x86_thiscallcc %struct.A* @"??0A@@QAE@XZ"
+// WIN32: invoke void @"?TakeRef@@YAXABUA@@@Z"
+// WIN32: invoke x86_thiscallcc %struct.A* @"??0A@@QAE@XZ"
+// WIN32: store i1 false, i1* %[[isactive]]
+//
+// WIN32: invoke i32 @"?TakesTwo@@YAHUA@@0@Z"([[argmem_ty]]* inalloca %[[argmem]])
+// Destroy the two const ref temporaries.
+// WIN32: call x86_thiscallcc void @"??1A@@QAE@XZ"({{.*}})
+// WIN32: call x86_thiscallcc void @"??1A@@QAE@XZ"({{.*}})
+// WIN32: ret i32
+//
+// Conditionally destroy arg1.
+// WIN32: %[[cond:.*]] = load i1, i1* %[[isactive]]
+// WIN32: br i1 %[[cond]]
+// WIN32: call x86_thiscallcc void @"??1A@@QAE@XZ"(%struct.A* %[[arg1]])
+// WIN32: }
+
+// Test putting the cleanups inside a conditional.
+int CouldThrow();
+int HasConditionalCleanup(bool cond) {
+ return (cond ? TakesTwo(A(), A()) : CouldThrow());
+}
+
+// WIN32-LABEL: define dso_local i32 @"?HasConditionalCleanup@@YAH_N@Z"(i1 zeroext %{{.*}}) {{.*}} {
+// WIN32: store i1 false
+// WIN32: br i1
+// WIN32: call i8* @llvm.stacksave()
+// WIN32: call x86_thiscallcc %struct.A* @"??0A@@QAE@XZ"(%struct.A* %{{.*}})
+// WIN32: store i1 true
+// WIN32: invoke x86_thiscallcc %struct.A* @"??0A@@QAE@XZ"(%struct.A* %{{.*}})
+// WIN32: call i32 @"?TakesTwo@@YAHUA@@0@Z"
+//
+// WIN32: call void @llvm.stackrestore
+//
+// WIN32: call i32 @"?CouldThrow@@YAHXZ"()
+//
+// Only one dtor in the invoke for arg1
+// WIN32: call x86_thiscallcc void @"??1A@@QAE@XZ"({{.*}})
+// WIN32-NOT: invoke x86_thiscallcc void @"??1A@@QAE@XZ"
+// WIN32: }
+
+// Now test both.
+int HasConditionalDeactivatedCleanups(bool cond) {
+ return (cond ? TakesTwo((TakeRef(A()), A()), (TakeRef(A()), A())) : CouldThrow());
+}
+
+// WIN32-O0-LABEL: define dso_local i32 @"?HasConditionalDeactivatedCleanups@@YAH_N@Z"{{.*}} {
+// WIN32-O0: alloca i1
+// WIN32-O0: %[[arg1_cond:.*]] = alloca i1
+// Start all four cleanups as deactivated.
+// WIN32-O0: store i1 false
+// WIN32-O0: store i1 false
+// WIN32-O0: store i1 false
+// WIN32-O0: store i1 false
+// WIN32-O0: br i1
+// True condition.
+// WIN32-O0: call x86_thiscallcc %struct.A* @"??0A@@QAE@XZ"
+// WIN32-O0: store i1 true
+// WIN32-O0: invoke void @"?TakeRef@@YAXABUA@@@Z"
+// WIN32-O0: invoke x86_thiscallcc %struct.A* @"??0A@@QAE@XZ"
+// WIN32-O0: store i1 true, i1* %[[arg1_cond]]
+// WIN32-O0: invoke x86_thiscallcc %struct.A* @"??0A@@QAE@XZ"
+// WIN32-O0: store i1 true
+// WIN32-O0: invoke void @"?TakeRef@@YAXABUA@@@Z"
+// WIN32-O0: invoke x86_thiscallcc %struct.A* @"??0A@@QAE@XZ"
+// WIN32-O0: store i1 true
+// WIN32-O0: store i1 false, i1* %[[arg1_cond]]
+// WIN32-O0: invoke i32 @"?TakesTwo@@YAHUA@@0@Z"
+// False condition.
+// WIN32-O0: invoke i32 @"?CouldThrow@@YAHXZ"()
+// Two normal cleanups for TakeRef args.
+// WIN32-O0: call x86_thiscallcc void @"??1A@@QAE@XZ"({{.*}})
+// WIN32-O0-NOT: invoke x86_thiscallcc void @"??1A@@QAE@XZ"
+// WIN32-O0: ret i32
+//
+// Somewhere in the landing pad soup, we conditionally destroy arg1.
+// WIN32-O0: %[[isactive:.*]] = load i1, i1* %[[arg1_cond]]
+// WIN32-O0: br i1 %[[isactive]]
+// WIN32-O0: call x86_thiscallcc void @"??1A@@QAE@XZ"({{.*}})
+// WIN32-O0: }
+
+// WIN32-O3-LABEL: define dso_local i32 @"?HasConditionalDeactivatedCleanups@@YAH_N@Z"{{.*}} {
+// WIN32-O3: alloca i1
+// WIN32-O3: alloca i1
+// WIN32-O3: %[[arg1_cond:.*]] = alloca i1
+// Start all four cleanups as deactivated.
+// WIN32-O3: store i1 false
+// WIN32-O3: store i1 false
+// WIN32-O3: store i1 false
+// WIN32-O3: store i1 false
+// WIN32-O3: store i1 false
+// WIN32-O3: store i1 false
+// WIN32-O3: br i1
+// True condition.
+// WIN32-O3: call x86_thiscallcc %struct.A* @"??0A@@QAE@XZ"
+// WIN32-O3: store i1 true
+// WIN32-O3: invoke void @"?TakeRef@@YAXABUA@@@Z"
+// WIN32-O3: invoke x86_thiscallcc %struct.A* @"??0A@@QAE@XZ"
+// WIN32-O3: store i1 true, i1* %[[arg1_cond]]
+// WIN32-O3: invoke x86_thiscallcc %struct.A* @"??0A@@QAE@XZ"
+// WIN32-O3: store i1 true
+// WIN32-O3: invoke void @"?TakeRef@@YAXABUA@@@Z"
+// WIN32-O3: invoke x86_thiscallcc %struct.A* @"??0A@@QAE@XZ"
+// WIN32-O3: store i1 true
+// WIN32-O3: store i1 false, i1* %[[arg1_cond]]
+// WIN32-O3: invoke i32 @"?TakesTwo@@YAHUA@@0@Z"
+// False condition.
+// WIN32-O3: invoke i32 @"?CouldThrow@@YAHXZ"()
+// Two normal cleanups for TakeRef args.
+// WIN32-O3: call x86_thiscallcc void @"??1A@@QAE@XZ"({{.*}})
+// WIN32-O3-NOT: invoke x86_thiscallcc void @"??1A@@QAE@XZ"
+// WIN32-O3: ret i32
+//
+// Somewhere in the landing pad soup, we conditionally destroy arg1.
+// WIN32-O3: %[[isactive:.*]] = load i1, i1* %[[arg1_cond]]
+// WIN32-O3: br i1 %[[isactive]]
+// WIN32-O3: call x86_thiscallcc void @"??1A@@QAE@XZ"({{.*}})
+// WIN32-O3: }
+
+namespace crash_on_partial_destroy {
+struct A {
+ virtual ~A();
+};
+
+struct B : virtual A {
+ // Has an implicit destructor.
+};
+
+struct C : B {
+ C();
+};
+
+void foo();
+// We used to crash when emitting this.
+C::C() { foo(); }
+
+// Verify that we don't bother with a vbtable lookup when adjusting the this
+// pointer to call a base destructor from a constructor while unwinding.
+// WIN32-LABEL: define dso_local {{.*}} @"??0C@crash_on_partial_destroy@@QAE@XZ"{{.*}} {
+// WIN32: cleanuppad
+//
+// We shouldn't do any vbptr loads, just constant GEPs.
+// WIN32-NOT: load
+// WIN32: getelementptr i8, i8* %{{.*}}, i32 4
+// WIN32-NOT: load
+// WIN32: bitcast i8* %{{.*}} to %"struct.crash_on_partial_destroy::B"*
+// WIN32: call x86_thiscallcc void @"??1B@crash_on_partial_destroy@@UAE@XZ"
+//
+// WIN32-NOT: load
+// WIN32: bitcast %"struct.crash_on_partial_destroy::C"* %{{.*}} to i8*
+// WIN32-NOT: load
+// WIN32: getelementptr inbounds i8, i8* %{{.*}}, i32 4
+// WIN32-NOT: load
+// WIN32: bitcast i8* %{{.*}} to %"struct.crash_on_partial_destroy::A"*
+// WIN32: call x86_thiscallcc void @"??1A@crash_on_partial_destroy@@UAE@XZ"({{.*}})
+// WIN32: }
+}
+
+namespace dont_call_terminate {
+struct C {
+ ~C();
+};
+void g();
+void f() {
+ C c;
+ g();
+}
+
+// WIN32-LABEL: define dso_local void @"?f@dont_call_terminate@@YAXXZ"()
+// WIN32: invoke void @"?g@dont_call_terminate@@YAXXZ"()
+// WIN32-NEXT: to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]
+//
+// WIN32: [[cont]]
+// WIN32: call x86_thiscallcc void @"??1C@dont_call_terminate@@QAE@XZ"({{.*}})
+//
+// WIN32: [[lpad]]
+// WIN32-NEXT: cleanuppad
+// WIN32: call x86_thiscallcc void @"??1C@dont_call_terminate@@QAE@XZ"({{.*}})
+}
+
+namespace noexcept_false_dtor {
+struct D {
+ ~D() noexcept(false);
+};
+void f() {
+ D d;
+ CouldThrow();
+}
+}
+
+// WIN32-LABEL: define dso_local void @"?f@noexcept_false_dtor@@YAXXZ"()
+// WIN32: invoke i32 @"?CouldThrow@@YAHXZ"()
+// WIN32: call x86_thiscallcc void @"??1D@noexcept_false_dtor@@QAE@XZ"(%"struct.noexcept_false_dtor::D"* %{{.*}})
+// WIN32: cleanuppad
+// WIN32: call x86_thiscallcc void @"??1D@noexcept_false_dtor@@QAE@XZ"(%"struct.noexcept_false_dtor::D"* %{{.*}})
+// WIN32: cleanupret
+
+namespace lifetime_marker {
+struct C {
+ ~C();
+};
+void g();
+void f() {
+ C c;
+ g();
+}
+
+// WIN32-LIFETIME-LABEL: define dso_local void @"?f@lifetime_marker@@YAXXZ"()
+// WIN32-LIFETIME: %[[c:.*]] = alloca %"struct.lifetime_marker::C"
+// WIN32-LIFETIME: %[[bc0:.*]] = bitcast %"struct.lifetime_marker::C"* %c to i8*
+// WIN32-LIFETIME: call void @llvm.lifetime.start.p0i8(i64 1, i8* %[[bc0]])
+// WIN32-LIFETIME: invoke void @"?g@lifetime_marker@@YAXXZ"()
+// WIN32-LIFETIME-NEXT: to label %[[cont:[^ ]*]] unwind label %[[lpad0:[^ ]*]]
+//
+// WIN32-LIFETIME: [[cont]]
+// WIN32-LIFETIME: call x86_thiscallcc void @"??1C@lifetime_marker@@QAE@XZ"({{.*}})
+// WIN32-LIFETIME: %[[bc1:.*]] = bitcast %"struct.lifetime_marker::C"* %[[c]] to i8*
+// WIN32-LIFETIME: call void @llvm.lifetime.end.p0i8(i64 1, i8* %[[bc1]])
+//
+// WIN32-LIFETIME: [[lpad0]]
+// WIN32-LIFETIME-NEXT: cleanuppad
+// WIN32-LIFETIME: call x86_thiscallcc void @"??1C@lifetime_marker@@QAE@XZ"({{.*}})
+// WIN32-LIFETIME: cleanupret {{.*}} unwind label %[[lpad1:[^ ]*]]
+//
+// WIN32-LIFETIME: [[lpad1]]
+// WIN32-LIFETIME-NEXT: cleanuppad
+// WIN32-LIFETIME: %[[bc2:.*]] = bitcast %"struct.lifetime_marker::C"* %[[c]] to i8*
+// WIN32-LIFETIME: call void @llvm.lifetime.end.p0i8(i64 1, i8* %[[bc2]])
+}
+
+struct class_2 {
+ class_2();
+ virtual ~class_2();
+};
+struct class_1 : virtual class_2 {
+ class_1(){throw "Unhandled exception";}
+ virtual ~class_1() {}
+};
+struct class_0 : class_1 {
+ class_0() ;
+ virtual ~class_0() {}
+};
+
+class_0::class_0() {
+ // WIN32: define dso_local x86_thiscallcc %struct.class_0* @"??0class_0@@QAE@XZ"(%struct.class_0* returned %this, i32 %is_most_derived)
+ // WIN32: store i32 %is_most_derived, i32* %[[IS_MOST_DERIVED_VAR:.*]], align 4
+ // WIN32: %[[IS_MOST_DERIVED_VAL:.*]] = load i32, i32* %[[IS_MOST_DERIVED_VAR]]
+ // WIN32: %[[SHOULD_CALL_VBASE_CTORS:.*]] = icmp ne i32 %[[IS_MOST_DERIVED_VAL]], 0
+ // WIN32: br i1 %[[SHOULD_CALL_VBASE_CTORS]], label %[[INIT_VBASES:.*]], label %[[SKIP_VBASES:.*]]
+ // WIN32: [[INIT_VBASES]]
+ // WIN32: br label %[[SKIP_VBASES]]
+ // WIN32: [[SKIP_VBASES]]
+// ehcleanup:
+ // WIN32: %[[CLEANUPPAD:.*]] = cleanuppad within none []
+ // WIN32-NEXT: bitcast %{{.*}}* %{{.*}} to i8*
+ // WIN32-NEXT: getelementptr inbounds i8, i8* %{{.*}}, i{{.*}} {{.}}
+ // WIN32-NEXT: bitcast i8* %{{.*}} to %{{.*}}*
+ // WIN32-NEXT: %[[SHOULD_CALL_VBASE_DTOR:.*]] = icmp ne i32 %[[IS_MOST_DERIVED_VAL]], 0
+ // WIN32-NEXT: br i1 %[[SHOULD_CALL_VBASE_DTOR]], label %[[DTOR_VBASE:.*]], label %[[SKIP_VBASE:.*]]
+ // WIN32: [[DTOR_VBASE]]
+ // WIN32-NEXT: call x86_thiscallcc void @"??1class_2@@UAE@XZ"
+ // WIN32: br label %[[SKIP_VBASE]]
+ // WIN32: [[SKIP_VBASE]]
+}
+
+namespace PR37146 {
+// Check that IRGen doesn't emit calls to synthesized destructors for
+// non-trival C structs.
+
+// WIN32: define dso_local void @"?test@PR37146@@YAXXZ"()
+// WIN32: call void @llvm.memset.p0i8.i32(
+// WIN32: call i32 @"?getS@PR37146@@YA?AUS@1@XZ"(
+// WIN32: call void @"?func@PR37146@@YAXUS@1@0@Z"(
+// WIN32-NEXT: ret void
+// WIN32-NEXT: {{^}$}}
+
+struct S {
+ int f;
+};
+
+void func(S, S);
+S getS();
+
+void test() {
+ func(getS(), S());
+}
+
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-eh-inlineasm.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-eh-inlineasm.cpp
new file mode 100644
index 0000000..4179508
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-eh-inlineasm.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=x86_64-pc-windows-msvc \
+// RUN: -fexceptions -fcxx-exceptions | FileCheck %s
+
+// Make sure calls to inline asm have funclet bundles.
+
+extern "C" void might_throw();
+extern "C" void foo() {
+ try {
+ might_throw();
+ } catch (int) {
+ __asm__("nop");
+ }
+}
+
+// CHECK-LABEL: define dso_local void @foo()
+// CHECK: invoke void @might_throw()
+// CHECK: %[[CATCHPAD:[^ ]*]] = catchpad within
+// CHECK: call void asm sideeffect "nop", {{.*}} [ "funclet"(token %[[CATCHPAD]]) ]
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-eh-terminate.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-eh-terminate.cpp
new file mode 100644
index 0000000..394b834
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-eh-terminate.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=x86_64-pc-windows-msvc -mconstructor-aliases -fexceptions -fcxx-exceptions -fms-compatibility-version=18.00 | FileCheck -check-prefix=MSVC2013 -check-prefix=CHECK %s
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=x86_64-pc-windows-msvc -mconstructor-aliases -fexceptions -fcxx-exceptions -fms-compatibility-version=19.00 | FileCheck -check-prefix=MSVC2015 -check-prefix=CHECK %s
+
+void may_throw();
+void never_throws() noexcept(true) {
+ may_throw();
+}
+
+// CHECK-LABEL: define dso_local void @"?never_throws@@YAXXZ"()
+// CHECK-SAME: personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
+// CHECK: invoke void @"?may_throw@@YAXXZ"()
+// CHECK: %[[cp:.*]] = cleanuppad within none []
+// MSVC2013: call void @"?terminate@@YAXXZ"()
+// MSVC2015: call void @__std_terminate()
+// CHECK-SAME: [ "funclet"(token %[[cp]]) ]
+// CHECK-NEXT: unreachable
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-emit-dependent.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-emit-dependent.cpp
new file mode 100644
index 0000000..e74ebc8
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-emit-dependent.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -emit-llvm-only -fmodules -triple x86_64-windows %s
+// PR36181
+#pragma clang module build foo
+module foo {}
+#pragma clang module contents
+template <typename T> struct A {
+ friend void f(A<T>) {}
+};
+#pragma clang module endbuild
+#pragma clang module import foo
+void g() { f(A<int>()); }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-extern-template.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-extern-template.cpp
new file mode 100644
index 0000000..8359236
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-extern-template.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -fno-rtti-data -O1 -disable-llvm-passes %s -emit-llvm -o - -triple x86_64-windows-msvc | FileCheck %s
+
+// Even though Foo<int> has an extern template declaration, we have to emit our
+// own copy the vftable when emitting the available externally constructor.
+
+// CHECK: @"??_7?$Foo@H@@6B@" = linkonce_odr unnamed_addr constant { [1 x i8*] } { [1 x i8*] [
+// CHECK-SAME: i8* bitcast (i8* (%struct.Foo*, i32)* @"??_G?$Foo@H@@UEAAPEAXI@Z" to i8*)
+// CHECK-SAME: ] }, comdat
+
+// CHECK-LABEL: define dso_local %struct.Foo* @"?f@@YAPEAU?$Foo@H@@XZ"()
+// CHECK: call %struct.Foo* @"??0?$Foo@H@@QEAA@XZ"(%struct.Foo* %{{.*}})
+
+// CHECK: define available_externally dso_local %struct.Foo* @"??0?$Foo@H@@QEAA@XZ"(%struct.Foo* returned %this)
+// CHECK: store {{.*}} @"??_7?$Foo@H@@6B@"
+
+// CHECK: define linkonce_odr dso_local i8* @"??_G?$Foo@H@@UEAAPEAXI@Z"(%struct.Foo* %this, i32 %should_call_delete)
+
+struct Base {
+ virtual ~Base();
+};
+template <typename T> struct Foo : Base {
+ Foo() {}
+};
+extern template class Foo<int>;
+Foo<int> *f() { return new Foo<int>(); }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-member-pointers.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-member-pointers.cpp
new file mode 100644
index 0000000..cb3b41b
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-member-pointers.cpp
@@ -0,0 +1,912 @@
+// RUN: %clang_cc1 -std=c++11 -Wno-uninitialized -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 -fms-extensions | FileCheck -allow-deprecated-dag-overlap %s
+// RUN: %clang_cc1 -std=c++11 -Wno-uninitialized -fno-rtti -emit-llvm %s -o - -triple=x86_64-pc-win32 -fms-extensions | FileCheck %s -check-prefix=X64
+// RUN: %clang_cc1 -std=c++11 -Wno-uninitialized -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 -DINCOMPLETE_VIRTUAL -fms-extensions -verify
+// RUN: %clang_cc1 -std=c++11 -Wno-uninitialized -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 -DINCOMPLETE_VIRTUAL -DMEMFUN -fms-extensions -verify
+
+namespace pr37399 {
+template <typename T>
+struct Functor {
+ void (T::*PtrToMemberFunction)();
+};
+// CHECK-DAG: %"struct.pr37399::Functor" = type { i8* }
+
+template <typename SomeType>
+class SimpleDerivedFunctor;
+template <typename SomeType>
+class SimpleDerivedFunctor : public Functor<SimpleDerivedFunctor<SomeType>> {};
+// CHECK-DAG: %"class.pr37399::SimpleDerivedFunctor" = type { %"struct.pr37399::Functor" }
+
+SimpleDerivedFunctor<void> SimpleFunctor;
+// CHECK-DAG: @"?SimpleFunctor@pr37399@@3V?$SimpleDerivedFunctor@X@1@A" = dso_local global %"class.pr37399::SimpleDerivedFunctor" zeroinitializer, align 4
+
+short Global = 0;
+template <typename SomeType>
+class DerivedFunctor;
+template <typename SomeType>
+class DerivedFunctor
+ : public Functor<DerivedFunctor<void>> {
+public:
+ void Foo() {
+ Global = 42;
+ }
+};
+
+class MultipleBase {
+public:
+ MultipleBase() : Value() {}
+ short Value;
+};
+// CHECK-DAG: %"class.pr37399::MultipleBase" = type { i16 }
+
+template <typename SomeType>
+class MultiplyDerivedFunctor;
+template <typename SomeType>
+class MultiplyDerivedFunctor
+ : public Functor<MultiplyDerivedFunctor<void>>,
+ public MultipleBase {
+public:
+ void Foo() {
+ MultipleBase::Value = 42*2;
+ }
+};
+
+class VirtualBase {
+public:
+ VirtualBase() : Value() {}
+ short Value;
+};
+// CHECK-DAG: %"class.pr37399::VirtualBase" = type { i16 }
+
+template <typename SomeType>
+class VirtBaseFunctor
+ : public Functor<SomeType>,
+ public virtual VirtualBase{};
+template <typename SomeType>
+class VirtuallyDerivedFunctor;
+template <typename SomeType>
+class VirtuallyDerivedFunctor
+ : public VirtBaseFunctor<VirtuallyDerivedFunctor<void>>,
+ public virtual VirtualBase {
+public:
+ void Foo() {
+ VirtualBase::Value = 42*3;
+ }
+};
+} // namespace pr37399
+
+pr37399::DerivedFunctor<int> BFunctor;
+// CHECK-DAG: @"?BFunctor@@3V?$DerivedFunctor@H@pr37399@@A" = dso_local global %"[[BFUNCTOR:class.pr37399::DerivedFunctor(\.[0-9]+)?]]" zeroinitializer, align 8
+// CHECK-DAG: %"[[BFUNCTOR]]" = type { %"[[BFUNCTORBASE:struct.pr37399::Functor(\.[0-9]+)?]]" }
+// CHECK-DAG: %"[[BFUNCTORBASE]]" = type { { i8*, i32, i32, i32 } }
+pr37399::DerivedFunctor<void> AFunctor;
+// CHECK-DAG: @"?AFunctor@@3V?$DerivedFunctor@X@pr37399@@A" = dso_local global %"[[AFUNCTOR:class.pr37399::DerivedFunctor(\.[0-9]+)?]]" zeroinitializer, align 8
+// CHECK-DAG: %"[[AFUNCTOR]]" = type { %"[[AFUNCTORBASE:struct.pr37399::Functor(\.[0-9]+)?]]" }
+// CHECK-DAG: %"[[AFUNCTORBASE]]" = type { { i8*, i32, i32, i32 } }
+
+pr37399::MultiplyDerivedFunctor<int> DFunctor;
+// CHECK-DAG: @"?DFunctor@@3V?$MultiplyDerivedFunctor@H@pr37399@@A" = dso_local global %"[[DFUNCTOR:class.pr37399::MultiplyDerivedFunctor(\.[0-9]+)?]]" zeroinitializer, align 8
+// CHECK-DAG: %"[[DFUNCTOR]]" = type { %"[[DFUNCTORBASE:struct.pr37399::Functor(\.[0-9]+)?]]", %"class.pr37399::MultipleBase", [6 x i8] }
+// CHECK-DAG: %"[[DFUNCTORBASE]]" = type { { i8*, i32, i32, i32 } }
+pr37399::MultiplyDerivedFunctor<void> CFunctor;
+// CHECK-DAG: @"?CFunctor@@3V?$MultiplyDerivedFunctor@X@pr37399@@A" = dso_local global %"[[CFUNCTOR:class.pr37399::MultiplyDerivedFunctor(\.[0-9]+)?]]" zeroinitializer, align 8
+// CHECK-DAG: %"[[CFUNCTOR]]" = type { %"[[CFUNCTORBASE:struct.pr37399::Functor(\.[0-9]+)?]]", %"class.pr37399::MultipleBase", [6 x i8] }
+// CHECK-DAG: %"[[CFUNCTORBASE]]" = type { { i8*, i32, i32, i32 } }
+
+pr37399::VirtuallyDerivedFunctor<int> FFunctor;
+// CHECK-DAG: @"?FFunctor@@3V?$VirtuallyDerivedFunctor@H@pr37399@@A" = dso_local global %"[[FFUNCTOR:class.pr37399::VirtuallyDerivedFunctor(\.[0-9]+)?]]" zeroinitializer, align 8
+// CHECK-DAG: %"[[FFUNCTOR]]" = type { %"class.pr37399::VirtBaseFunctor.base", %"class.pr37399::VirtualBase" }
+pr37399::VirtuallyDerivedFunctor<void> EFunctor;
+// CHECK-DAG: @"?EFunctor@@3V?$VirtuallyDerivedFunctor@X@pr37399@@A" = dso_local global %"[[EFUNCTOR:class.pr37399::VirtuallyDerivedFunctor(\.[0-9]+)?]]" zeroinitializer, align 8
+// CHECK-DAG: %"[[EFUNCTOR]]" = type { %"class.pr37399::VirtBaseFunctor.base", %"class.pr37399::VirtualBase" }
+
+// CHECK-DAG: %"class.pr37399::VirtBaseFunctor.base" = type <{ %"[[VFUNCTORBASE:struct.pr37399::Functor(\.[0-9]+)?]]", i32*, [4 x i8] }>
+// CHECK-DAG: %"[[VFUNCTORBASE]]" = type { { i8*, i32, i32, i32 } }
+
+namespace pr37399 {
+void SingleInheritanceFnPtrCall() {
+ BFunctor.PtrToMemberFunction = &DerivedFunctor<void>::Foo;
+ (AFunctor.*(BFunctor.PtrToMemberFunction))();
+}
+void MultipleInheritanceFnPtrCall() {
+ DFunctor.PtrToMemberFunction = &MultiplyDerivedFunctor<void>::Foo;
+ Global = CFunctor.MultipleBase::Value;
+ (CFunctor.*(DFunctor.PtrToMemberFunction))();
+ Global = CFunctor.MultipleBase::Value;
+}
+void VirtualInheritanceFnPtrCall() {
+ FFunctor.PtrToMemberFunction = &VirtuallyDerivedFunctor<void>::Foo;
+ Global = EFunctor.VirtualBase::Value;
+ (EFunctor.*(FFunctor.PtrToMemberFunction))();
+ Global = EFunctor.VirtualBase::Value;
+}
+} // namespace pr37399
+
+struct PR26313_Y;
+typedef void (PR26313_Y::*PR26313_FUNC)();
+struct PR26313_X {
+ PR26313_FUNC *ptr;
+ PR26313_X();
+};
+PR26313_X::PR26313_X() {}
+void PR26313_f(PR26313_FUNC *p) { delete p; }
+
+struct PR26313_Z;
+int PR26313_Z::**a = nullptr;
+int PR26313_Z::*b = *a;
+// CHECK-DAG: @"?a@@3PAPQPR26313_Z@@HA" = dso_local global %0* null, align 4
+// CHECK-DAG: @"?b@@3PQPR26313_Z@@HQ1@" = dso_local global { i32, i32, i32 } { i32 0, i32 0, i32 -1 }, align 4
+
+namespace PR20947 {
+struct A;
+int A::**a = nullptr;
+// CHECK-DAG: @"?a@PR20947@@3PAPQA@1@HA" = dso_local global %{{.*}}* null, align 4
+
+struct B;
+int B::*&b = b;
+// CHECK-DAG: @"?b@PR20947@@3AAPQB@1@HA" = dso_local global %{{.*}}* null, align 4
+}
+
+namespace PR20017 {
+template <typename T>
+struct A {
+ int T::*m_fn1() { return nullptr; }
+};
+struct B;
+auto a = &A<B>::m_fn1;
+// CHECK-DAG: @"?a@PR20017@@3P8?$A@UB@PR20017@@@1@AEPQB@1@HXZQ21@" = dso_local global i8* bitcast ({ i32, i32, i32 } ({{.*}}*)* @"?m_fn1@?$A@UB@PR20017@@@PR20017@@QAEPQB@2@HXZ" to i8*), align 4
+}
+
+#ifndef INCOMPLETE_VIRTUAL
+struct B1 {
+ void foo();
+ int b;
+};
+struct B2 {
+ int b2;
+ void foo();
+};
+struct Single : B1 {
+ void foo();
+};
+struct Multiple : B1, B2 {
+ int m;
+ void foo();
+};
+struct Virtual : virtual B1 {
+ int v;
+ void foo();
+};
+
+struct POD {
+ int a;
+ int b;
+};
+
+struct Polymorphic {
+ virtual void myVirtual();
+ int a;
+ int b;
+};
+
+// This class uses the virtual inheritance model, yet its vbptr offset is not 0.
+// We still use zero for the null field offset, despite it being a valid field
+// offset.
+struct NonZeroVBPtr : POD, Virtual {
+ int n;
+ void foo();
+};
+
+struct Unspecified;
+struct UnspecSingle;
+
+// Check that we can lower the LLVM types and get the null initializers right.
+int Single ::*s_d_memptr;
+int Polymorphic::*p_d_memptr;
+int Multiple ::*m_d_memptr;
+int Virtual ::*v_d_memptr;
+int NonZeroVBPtr::*n_d_memptr;
+int Unspecified::*u_d_memptr;
+int UnspecSingle::*us_d_memptr;
+// CHECK: @"?s_d_memptr@@3PQSingle@@HQ1@" = dso_local global i32 -1, align 4
+// CHECK: @"?p_d_memptr@@3PQPolymorphic@@HQ1@" = dso_local global i32 0, align 4
+// CHECK: @"?m_d_memptr@@3PQMultiple@@HQ1@" = dso_local global i32 -1, align 4
+// CHECK: @"?v_d_memptr@@3PQVirtual@@HQ1@" = dso_local global { i32, i32 }
+// CHECK: { i32 0, i32 -1 }, align 4
+// CHECK: @"?n_d_memptr@@3PQNonZeroVBPtr@@HQ1@" = dso_local global { i32, i32 }
+// CHECK: { i32 0, i32 -1 }, align 4
+// CHECK: @"?u_d_memptr@@3PQUnspecified@@HQ1@" = dso_local global { i32, i32, i32 }
+// CHECK: { i32 0, i32 0, i32 -1 }, align 4
+// CHECK: @"?us_d_memptr@@3PQUnspecSingle@@HQ1@" = dso_local global { i32, i32, i32 }
+// CHECK: { i32 0, i32 0, i32 -1 }, align 4
+
+void (Single ::*s_f_memptr)();
+void (Multiple::*m_f_memptr)();
+void (Virtual ::*v_f_memptr)();
+// CHECK: @"?s_f_memptr@@3P8Single@@AEXXZQ1@" = dso_local global i8* null, align 4
+// CHECK: @"?m_f_memptr@@3P8Multiple@@AEXXZQ1@" = dso_local global { i8*, i32 } zeroinitializer, align 4
+// CHECK: @"?v_f_memptr@@3P8Virtual@@AEXXZQ1@" = dso_local global { i8*, i32, i32 } zeroinitializer, align 4
+
+// We can define Unspecified after locking in the inheritance model.
+struct Unspecified : Multiple, Virtual {
+ void foo();
+ int u;
+};
+
+struct UnspecSingle {
+ void foo();
+};
+
+// Test memptr emission in a constant expression.
+namespace Const {
+void (Single ::*s_f_mp)() = &Single::foo;
+void (Multiple ::*m_f_mp)() = &B2::foo;
+void (Virtual ::*v_f_mp)() = &Virtual::foo;
+void (Unspecified::*u_f_mp)() = &Unspecified::foo;
+void (UnspecSingle::*us_f_mp)() = &UnspecSingle::foo;
+// CHECK: @"?s_f_mp@Const@@3P8Single@@AEXXZQ2@" =
+// CHECK: global i8* bitcast ({{.*}} @"?foo@Single@@QAEXXZ" to i8*), align 4
+// CHECK: @"?m_f_mp@Const@@3P8Multiple@@AEXXZQ2@" =
+// CHECK: global { i8*, i32 } { i8* bitcast ({{.*}} @"?foo@B2@@QAEXXZ" to i8*), i32 4 }, align 4
+// CHECK: @"?v_f_mp@Const@@3P8Virtual@@AEXXZQ2@" =
+// CHECK: global { i8*, i32, i32 } { i8* bitcast ({{.*}} @"?foo@Virtual@@QAEXXZ" to i8*), i32 0, i32 0 }, align 4
+// CHECK: @"?u_f_mp@Const@@3P8Unspecified@@AEXXZQ2@" =
+// CHECK: global { i8*, i32, i32, i32 } { i8* bitcast ({{.*}} @"?foo@Unspecified@@QAEXXZ" to i8*), i32 0, i32 0, i32 0 }, align 4
+// CHECK: @"?us_f_mp@Const@@3P8UnspecSingle@@AEXXZQ2@" =
+// CHECK: global { i8*, i32, i32, i32 } { i8* bitcast ({{.*}} @"?foo@UnspecSingle@@QAEXXZ" to i8*), i32 0, i32 0, i32 0 }, align 4
+}
+
+namespace CastParam {
+// This exercises ConstExprEmitter instead of ValueDecl::evaluateValue. The
+// extra reinterpret_cast for the parameter type requires more careful folding.
+// FIXME: Or does it? If reinterpret_casts are no-ops, we should be able to
+// strip them in evaluateValue() and just proceed as normal with an APValue.
+struct A {
+ int a;
+ void foo(A *p);
+};
+struct B { int b; };
+struct C : B, A { int c; };
+
+void (A::*ptr1)(void *) = (void (A::*)(void *)) &A::foo;
+// CHECK: @"?ptr1@CastParam@@3P8A@1@AEXPAX@ZQ21@" =
+// CHECK: global i8* bitcast (void ({{.*}})* @"?foo@A@CastParam@@QAEXPAU12@@Z" to i8*), align 4
+
+// Try a reinterpret_cast followed by a memptr conversion.
+void (C::*ptr2)(void *) = (void (C::*)(void *)) (void (A::*)(void *)) &A::foo;
+// CHECK: @"?ptr2@CastParam@@3P8C@1@AEXPAX@ZQ21@" =
+// CHECK: global { i8*, i32 } { i8* bitcast (void ({{.*}})* @"?foo@A@CastParam@@QAEXPAU12@@Z" to i8*), i32 4 }, align 4
+
+void (C::*ptr3)(void *) = (void (C::*)(void *)) (void (A::*)(void *)) (void (A::*)(A *)) 0;
+// CHECK: @"?ptr3@CastParam@@3P8C@1@AEXPAX@ZQ21@" =
+// CHECK: global { i8*, i32 } zeroinitializer, align 4
+
+struct D : C {
+ virtual void isPolymorphic();
+ int d;
+};
+
+// Try a cast that changes the inheritance model. Null for D is 0, but null for
+// C is -1. We need the cast to long in order to hit the non-APValue path.
+int C::*ptr4 = (int C::*) (int D::*) (long D::*) 0;
+// CHECK: @"?ptr4@CastParam@@3PQC@1@HQ21@" = dso_local global i32 -1, align 4
+
+// MSVC rejects this but we accept it.
+int C::*ptr5 = (int C::*) (long D::*) 0;
+// CHECK: @"?ptr5@CastParam@@3PQC@1@HQ21@" = dso_local global i32 -1, align 4
+}
+
+struct UnspecWithVBPtr;
+int UnspecWithVBPtr::*forceUnspecWithVBPtr;
+struct UnspecWithVBPtr : B1, virtual B2 {
+ int u;
+ void foo();
+};
+
+// Test emitting non-virtual member pointers in a non-constexpr setting.
+void EmitNonVirtualMemberPointers() {
+ void (Single ::*s_f_memptr)() = &Single::foo;
+ void (Multiple ::*m_f_memptr)() = &Multiple::foo;
+ void (Virtual ::*v_f_memptr)() = &Virtual::foo;
+ void (Unspecified::*u_f_memptr)() = &Unspecified::foo;
+ void (UnspecWithVBPtr::*u2_f_memptr)() = &UnspecWithVBPtr::foo;
+// CHECK: define dso_local void @"?EmitNonVirtualMemberPointers@@YAXXZ"() {{.*}} {
+// CHECK: alloca i8*, align 4
+// CHECK: alloca { i8*, i32 }, align 4
+// CHECK: alloca { i8*, i32, i32 }, align 4
+// CHECK: alloca { i8*, i32, i32, i32 }, align 4
+// CHECK: store i8* bitcast (void (%{{.*}}*)* @"?foo@Single@@QAEXXZ" to i8*), i8** %{{.*}}, align 4
+// CHECK: store { i8*, i32 }
+// CHECK: { i8* bitcast (void (%{{.*}}*)* @"?foo@Multiple@@QAEXXZ" to i8*), i32 0 },
+// CHECK: { i8*, i32 }* %{{.*}}, align 4
+// CHECK: store { i8*, i32, i32 }
+// CHECK: { i8* bitcast (void (%{{.*}}*)* @"?foo@Virtual@@QAEXXZ" to i8*), i32 0, i32 0 },
+// CHECK: { i8*, i32, i32 }* %{{.*}}, align 4
+// CHECK: store { i8*, i32, i32, i32 }
+// CHECK: { i8* bitcast (void (%{{.*}}*)* @"?foo@Unspecified@@QAEXXZ" to i8*), i32 0, i32 0, i32 0 },
+// CHECK: { i8*, i32, i32, i32 }* %{{.*}}, align 4
+// CHECK: store { i8*, i32, i32, i32 }
+// CHECK: { i8* bitcast (void (%{{.*}}*)* @"?foo@UnspecWithVBPtr@@QAEXXZ" to i8*),
+// CHECK: i32 0, i32 0, i32 0 },
+// CHECK: { i8*, i32, i32, i32 }* %{{.*}}, align 4
+// CHECK: ret void
+// CHECK: }
+}
+
+void podMemPtrs() {
+ int POD::*memptr;
+ memptr = &POD::a;
+ memptr = &POD::b;
+ if (memptr)
+ memptr = 0;
+// Check that member pointers use the right offsets and that null is -1.
+// CHECK: define dso_local void @"?podMemPtrs@@YAXXZ"() {{.*}} {
+// CHECK: %[[memptr:.*]] = alloca i32, align 4
+// CHECK-NEXT: store i32 0, i32* %[[memptr]], align 4
+// CHECK-NEXT: store i32 4, i32* %[[memptr]], align 4
+// CHECK-NEXT: %[[memptr_val:.*]] = load i32, i32* %[[memptr]], align 4
+// CHECK-NEXT: %{{.*}} = icmp ne i32 %[[memptr_val]], -1
+// CHECK-NEXT: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}
+// CHECK: store i32 -1, i32* %[[memptr]], align 4
+// CHECK: ret void
+// CHECK: }
+}
+
+void polymorphicMemPtrs() {
+ int Polymorphic::*memptr;
+ memptr = &Polymorphic::a;
+ memptr = &Polymorphic::b;
+ if (memptr)
+ memptr = 0;
+// Member pointers for polymorphic classes include the vtable slot in their
+// offset and use 0 to represent null.
+// CHECK: define dso_local void @"?polymorphicMemPtrs@@YAXXZ"() {{.*}} {
+// CHECK: %[[memptr:.*]] = alloca i32, align 4
+// CHECK-NEXT: store i32 4, i32* %[[memptr]], align 4
+// CHECK-NEXT: store i32 8, i32* %[[memptr]], align 4
+// CHECK-NEXT: %[[memptr_val:.*]] = load i32, i32* %[[memptr]], align 4
+// CHECK-NEXT: %{{.*}} = icmp ne i32 %[[memptr_val]], 0
+// CHECK-NEXT: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}
+// CHECK: store i32 0, i32* %[[memptr]], align 4
+// CHECK: ret void
+// CHECK: }
+}
+
+bool nullTestDataUnspecified(int Unspecified::*mp) {
+ return mp;
+// CHECK: define dso_local zeroext i1 @"?nullTestDataUnspecified@@YA_NPQUnspecified@@H@Z"{{.*}} {
+// CHECK: %{{.*}} = load { i32, i32, i32 }, { i32, i32, i32 }* %{{.*}}, align 4
+// CHECK: store { i32, i32, i32 } {{.*}} align 4
+// CHECK: %[[mp:.*]] = load { i32, i32, i32 }, { i32, i32, i32 }* %{{.*}}, align 4
+// CHECK: %[[mp0:.*]] = extractvalue { i32, i32, i32 } %[[mp]], 0
+// CHECK: %[[cmp0:.*]] = icmp ne i32 %[[mp0]], 0
+// CHECK: %[[mp1:.*]] = extractvalue { i32, i32, i32 } %[[mp]], 1
+// CHECK: %[[cmp1:.*]] = icmp ne i32 %[[mp1]], 0
+// CHECK: %[[and0:.*]] = or i1 %[[cmp0]], %[[cmp1]]
+// CHECK: %[[mp2:.*]] = extractvalue { i32, i32, i32 } %[[mp]], 2
+// CHECK: %[[cmp2:.*]] = icmp ne i32 %[[mp2]], -1
+// CHECK: %[[and1:.*]] = or i1 %[[and0]], %[[cmp2]]
+// CHECK: ret i1 %[[and1]]
+// CHECK: }
+
+// Pass this large type indirectly.
+// X64-LABEL: define dso_local zeroext i1 @"?nullTestDataUnspecified@@
+// X64: ({ i32, i32, i32 }*)
+}
+
+bool nullTestFunctionUnspecified(void (Unspecified::*mp)()) {
+ return mp;
+// CHECK: define dso_local zeroext i1 @"?nullTestFunctionUnspecified@@YA_NP8Unspecified@@AEXXZ@Z"{{.*}} {
+// CHECK: %{{.*}} = load { i8*, i32, i32, i32 }, { i8*, i32, i32, i32 }* %{{.*}}, align 4
+// CHECK: store { i8*, i32, i32, i32 } {{.*}} align 4
+// CHECK: %[[mp:.*]] = load { i8*, i32, i32, i32 }, { i8*, i32, i32, i32 }* %{{.*}}, align 4
+// CHECK: %[[mp0:.*]] = extractvalue { i8*, i32, i32, i32 } %[[mp]], 0
+// CHECK: %[[cmp0:.*]] = icmp ne i8* %[[mp0]], null
+// CHECK: ret i1 %[[cmp0]]
+// CHECK: }
+}
+
+int loadDataMemberPointerVirtual(Virtual *o, int Virtual::*memptr) {
+ return o->*memptr;
+// Test that we can unpack this aggregate member pointer and load the member
+// data pointer.
+// CHECK: define dso_local i32 @"?loadDataMemberPointerVirtual@@YAHPAUVirtual@@PQ1@H@Z"{{.*}} {
+// CHECK: %[[o:.*]] = load %{{.*}}*, %{{.*}}** %{{.*}}, align 4
+// CHECK: %[[memptr:.*]] = load { i32, i32 }, { i32, i32 }* %{{.*}}, align 4
+// CHECK: %[[memptr0:.*]] = extractvalue { i32, i32 } %[[memptr:.*]], 0
+// CHECK: %[[memptr1:.*]] = extractvalue { i32, i32 } %[[memptr:.*]], 1
+// CHECK: %[[v6:.*]] = bitcast %{{.*}}* %[[o]] to i8*
+// CHECK: %[[vbptr:.*]] = getelementptr inbounds i8, i8* %[[v6]], i32 0
+// CHECK: %[[vbptr_a:.*]] = bitcast i8* %[[vbptr]] to i32**
+// CHECK: %[[vbtable:.*]] = load i32*, i32** %[[vbptr_a:.*]]
+// CHECK: %[[memptr1_shr:.*]] = ashr exact i32 %[[memptr1]], 2
+// CHECK: %[[v7:.*]] = getelementptr inbounds i32, i32* %[[vbtable]], i32 %[[memptr1_shr]]
+// CHECK: %[[vbase_offs:.*]] = load i32, i32* %[[v7]]
+// CHECK: %[[v10:.*]] = getelementptr inbounds i8, i8* %[[vbptr]], i32 %[[vbase_offs]]
+// CHECK: %[[offset:.*]] = getelementptr inbounds i8, i8* %[[v10]], i32 %[[memptr0]]
+// CHECK: %[[v11:.*]] = bitcast i8* %[[offset]] to i32*
+// CHECK: %[[v12:.*]] = load i32, i32* %[[v11]]
+// CHECK: ret i32 %[[v12]]
+// CHECK: }
+
+// A two-field data memptr on x64 gets coerced to i64 and is passed in a
+// register or memory.
+// X64-LABEL: define dso_local i32 @"?loadDataMemberPointerVirtual@@YAHPEAUVirtual@@PEQ1@H@Z"
+// X64: (%struct.Virtual* %o, i64 %memptr.coerce)
+}
+
+int loadDataMemberPointerUnspecified(Unspecified *o, int Unspecified::*memptr) {
+ return o->*memptr;
+// Test that we can unpack this aggregate member pointer and load the member
+// data pointer.
+// CHECK: define dso_local i32 @"?loadDataMemberPointerUnspecified@@YAHPAUUnspecified@@PQ1@H@Z"{{.*}} {
+// CHECK: %[[o:.*]] = load %{{.*}}*, %{{.*}}** %{{.*}}, align 4
+// CHECK: %[[memptr:.*]] = load { i32, i32, i32 }, { i32, i32, i32 }* %{{.*}}, align 4
+// CHECK: %[[memptr0:.*]] = extractvalue { i32, i32, i32 } %[[memptr:.*]], 0
+// CHECK: %[[memptr1:.*]] = extractvalue { i32, i32, i32 } %[[memptr:.*]], 1
+// CHECK: %[[memptr2:.*]] = extractvalue { i32, i32, i32 } %[[memptr:.*]], 2
+// CHECK: %[[base:.*]] = bitcast %{{.*}}* %[[o]] to i8*
+// CHECK: %[[is_vbase:.*]] = icmp ne i32 %[[memptr2]], 0
+// CHECK: br i1 %[[is_vbase]], label %[[vadjust:.*]], label %[[skip:.*]]
+//
+// CHECK: [[vadjust]]
+// CHECK: %[[vbptr:.*]] = getelementptr inbounds i8, i8* %[[base]], i32 %[[memptr1]]
+// CHECK: %[[vbptr_a:.*]] = bitcast i8* %[[vbptr]] to i32**
+// CHECK: %[[vbtable:.*]] = load i32*, i32** %[[vbptr_a:.*]]
+// CHECK: %[[memptr2_shr:.*]] = ashr exact i32 %[[memptr2]], 2
+// CHECK: %[[v7:.*]] = getelementptr inbounds i32, i32* %[[vbtable]], i32 %[[memptr2_shr]]
+// CHECK: %[[vbase_offs:.*]] = load i32, i32* %[[v7]]
+// CHECK: %[[base_adj:.*]] = getelementptr inbounds i8, i8* %[[vbptr]], i32 %[[vbase_offs]]
+//
+// CHECK: [[skip]]
+// CHECK: %[[new_base:.*]] = phi i8* [ %[[base]], %{{.*}} ], [ %[[base_adj]], %[[vadjust]] ]
+// CHECK: %[[offset:.*]] = getelementptr inbounds i8, i8* %[[new_base]], i32 %[[memptr0]]
+// CHECK: %[[v11:.*]] = bitcast i8* %[[offset]] to i32*
+// CHECK: %[[v12:.*]] = load i32, i32* %[[v11]]
+// CHECK: ret i32 %[[v12]]
+// CHECK: }
+}
+
+void callMemberPointerSingle(Single *o, void (Single::*memptr)()) {
+ (o->*memptr)();
+// Just look for an indirect thiscall.
+// CHECK: define dso_local void @"?callMemberPointerSingle@@{{.*}} {{.*}} {
+// CHECK: call x86_thiscallcc void %{{.*}}(%{{.*}} %{{.*}})
+// CHECK: ret void
+// CHECK: }
+
+// X64-LABEL: define dso_local void @"?callMemberPointerSingle@@
+// X64: (%struct.Single* %o, i8* %memptr)
+// X64: bitcast i8* %{{[^ ]*}} to void (%struct.Single*)*
+// X64: ret void
+}
+
+void callMemberPointerMultiple(Multiple *o, void (Multiple::*memptr)()) {
+ (o->*memptr)();
+// CHECK: define dso_local void @"?callMemberPointerMultiple@@{{.*}} {
+// CHECK: %[[memptr0:.*]] = extractvalue { i8*, i32 } %{{.*}}, 0
+// CHECK: %[[memptr1:.*]] = extractvalue { i8*, i32 } %{{.*}}, 1
+// CHECK: %[[this_adjusted:.*]] = getelementptr inbounds i8, i8* %{{.*}}, i32 %[[memptr1]]
+// CHECK: %[[this:.*]] = bitcast i8* %[[this_adjusted]] to {{.*}}
+// CHECK: %[[fptr:.*]] = bitcast i8* %[[memptr0]] to {{.*}}
+// CHECK: call x86_thiscallcc void %[[fptr]](%{{.*}} %[[this]])
+// CHECK: ret void
+// CHECK: }
+}
+
+void callMemberPointerVirtualBase(Virtual *o, void (Virtual::*memptr)()) {
+ (o->*memptr)();
+// This shares a lot with virtual data member pointers.
+// CHECK: define dso_local void @"?callMemberPointerVirtualBase@@{{.*}} {
+// CHECK: %[[memptr0:.*]] = extractvalue { i8*, i32, i32 } %{{.*}}, 0
+// CHECK: %[[memptr1:.*]] = extractvalue { i8*, i32, i32 } %{{.*}}, 1
+// CHECK: %[[memptr2:.*]] = extractvalue { i8*, i32, i32 } %{{.*}}, 2
+// CHECK: %[[vbptr:.*]] = getelementptr inbounds i8, i8* %{{.*}}, i32 0
+// CHECK: %[[vbptr_a:.*]] = bitcast i8* %[[vbptr]] to i32**
+// CHECK: %[[vbtable:.*]] = load i32*, i32** %[[vbptr_a:.*]]
+// CHECK: %[[memptr2_shr:.*]] = ashr exact i32 %[[memptr2]], 2
+// CHECK: %[[v7:.*]] = getelementptr inbounds i32, i32* %[[vbtable]], i32 %[[memptr2_shr]]
+// CHECK: %[[vbase_offs:.*]] = load i32, i32* %[[v7]]
+// CHECK: %[[v10:.*]] = getelementptr inbounds i8, i8* %[[vbptr]], i32 %[[vbase_offs]]
+// CHECK: %[[this_adjusted:.*]] = getelementptr inbounds i8, i8* %[[v10]], i32 %[[memptr1]]
+// CHECK: %[[fptr:.*]] = bitcast i8* %[[memptr0]] to void ({{.*}})
+// CHECK: %[[this:.*]] = bitcast i8* %[[this_adjusted]] to {{.*}}
+// CHECK: call x86_thiscallcc void %[[fptr]](%{{.*}} %[[this]])
+// CHECK: ret void
+// CHECK: }
+}
+
+bool compareSingleFunctionMemptr(void (Single::*l)(), void (Single::*r)()) {
+ return l == r;
+// Should only be one comparison here.
+// CHECK: define dso_local zeroext i1 @"?compareSingleFunctionMemptr@@YA_NP8Single@@AEXXZ0@Z"{{.*}} {
+// CHECK-NOT: icmp
+// CHECK: %[[r:.*]] = icmp eq
+// CHECK-NOT: icmp
+// CHECK: ret i1 %[[r]]
+// CHECK: }
+
+// X64-LABEL: define dso_local zeroext i1 @"?compareSingleFunctionMemptr@@
+// X64: (i8* %{{[^,]*}}, i8* %{{[^)]*}})
+}
+
+bool compareNeqSingleFunctionMemptr(void (Single::*l)(), void (Single::*r)()) {
+ return l != r;
+// Should only be one comparison here.
+// CHECK: define dso_local zeroext i1 @"?compareNeqSingleFunctionMemptr@@YA_NP8Single@@AEXXZ0@Z"{{.*}} {
+// CHECK-NOT: icmp
+// CHECK: %[[r:.*]] = icmp ne
+// CHECK-NOT: icmp
+// CHECK: ret i1 %[[r]]
+// CHECK: }
+}
+
+bool unspecFuncMemptrEq(void (Unspecified::*l)(), void (Unspecified::*r)()) {
+ return l == r;
+// CHECK: define dso_local zeroext i1 @"?unspecFuncMemptrEq@@YA_NP8Unspecified@@AEXXZ0@Z"{{.*}} {
+// CHECK: %[[lhs0:.*]] = extractvalue { i8*, i32, i32, i32 } %[[l:.*]], 0
+// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[r:.*]], 0
+// CHECK: %[[cmp0:.*]] = icmp eq i8* %[[lhs0]], %{{.*}}
+// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[l]], 1
+// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[r]], 1
+// CHECK: %[[cmp1:.*]] = icmp eq i32
+// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[l]], 2
+// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[r]], 2
+// CHECK: %[[cmp2:.*]] = icmp eq i32
+// CHECK: %[[res12:.*]] = and i1 %[[cmp1]], %[[cmp2]]
+// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[l]], 3
+// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[r]], 3
+// CHECK: %[[cmp3:.*]] = icmp eq i32
+// CHECK: %[[res123:.*]] = and i1 %[[res12]], %[[cmp3]]
+// CHECK: %[[iszero:.*]] = icmp eq i8* %[[lhs0]], null
+// CHECK: %[[bits_or_null:.*]] = or i1 %[[res123]], %[[iszero]]
+// CHECK: %{{.*}} = and i1 %[[bits_or_null]], %[[cmp0]]
+// CHECK: ret i1 %{{.*}}
+// CHECK: }
+
+// X64-LABEL: define dso_local zeroext i1 @"?unspecFuncMemptrEq@@
+// X64: ({ i8*, i32, i32, i32 }*, { i8*, i32, i32, i32 }*)
+}
+
+bool unspecFuncMemptrNeq(void (Unspecified::*l)(), void (Unspecified::*r)()) {
+ return l != r;
+// CHECK: define dso_local zeroext i1 @"?unspecFuncMemptrNeq@@YA_NP8Unspecified@@AEXXZ0@Z"{{.*}} {
+// CHECK: %[[lhs0:.*]] = extractvalue { i8*, i32, i32, i32 } %[[l:.*]], 0
+// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[r:.*]], 0
+// CHECK: %[[cmp0:.*]] = icmp ne i8* %[[lhs0]], %{{.*}}
+// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[l]], 1
+// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[r]], 1
+// CHECK: %[[cmp1:.*]] = icmp ne i32
+// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[l]], 2
+// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[r]], 2
+// CHECK: %[[cmp2:.*]] = icmp ne i32
+// CHECK: %[[res12:.*]] = or i1 %[[cmp1]], %[[cmp2]]
+// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[l]], 3
+// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[r]], 3
+// CHECK: %[[cmp3:.*]] = icmp ne i32
+// CHECK: %[[res123:.*]] = or i1 %[[res12]], %[[cmp3]]
+// CHECK: %[[iszero:.*]] = icmp ne i8* %[[lhs0]], null
+// CHECK: %[[bits_or_null:.*]] = and i1 %[[res123]], %[[iszero]]
+// CHECK: %{{.*}} = or i1 %[[bits_or_null]], %[[cmp0]]
+// CHECK: ret i1 %{{.*}}
+// CHECK: }
+}
+
+bool unspecDataMemptrEq(int Unspecified::*l, int Unspecified::*r) {
+ return l == r;
+// CHECK: define dso_local zeroext i1 @"?unspecDataMemptrEq@@YA_NPQUnspecified@@H0@Z"{{.*}} {
+// CHECK: extractvalue { i32, i32, i32 } %{{.*}}, 0
+// CHECK: extractvalue { i32, i32, i32 } %{{.*}}, 0
+// CHECK: icmp eq i32
+// CHECK: extractvalue { i32, i32, i32 } %{{.*}}, 1
+// CHECK: extractvalue { i32, i32, i32 } %{{.*}}, 1
+// CHECK: icmp eq i32
+// CHECK: extractvalue { i32, i32, i32 } %{{.*}}, 2
+// CHECK: extractvalue { i32, i32, i32 } %{{.*}}, 2
+// CHECK: icmp eq i32
+// CHECK: and i1
+// CHECK: and i1
+// CHECK: ret i1
+// CHECK: }
+
+// X64-LABEL: define dso_local zeroext i1 @"?unspecDataMemptrEq@@
+// X64: ({ i32, i32, i32 }*, { i32, i32, i32 }*)
+}
+
+void (Multiple::*convertB2FuncToMultiple(void (B2::*mp)()))() {
+ return mp;
+// CHECK: define dso_local i64 @"?convertB2FuncToMultiple@@YAP8Multiple@@AEXXZP8B2@@AEXXZ@Z"{{.*}} {
+// CHECK: store
+// CHECK: %[[mp:.*]] = load i8*, i8** %{{.*}}, align 4
+// CHECK: icmp ne i8* %[[mp]], null
+// CHECK: br i1 %{{.*}} label %{{.*}}, label %{{.*}}
+//
+// memptr.convert: ; preds = %entry
+// CHECK: insertvalue { i8*, i32 } undef, i8* %[[mp]], 0
+// CHECK: insertvalue { i8*, i32 } %{{.*}}, i32 4, 1
+// CHECK: br label
+//
+// memptr.converted: ; preds = %memptr.convert, %entry
+// CHECK: phi { i8*, i32 } [ zeroinitializer, %{{.*}} ], [ {{.*}} ]
+// CHECK: }
+}
+
+void (B2::*convertMultipleFuncToB2(void (Multiple::*mp)()))() {
+// FIXME: cl emits warning C4407 on this code because of the representation
+// change. We might want to do the same.
+ return static_cast<void (B2::*)()>(mp);
+// FIXME: We should return i8* instead of i32 here. The ptrtoint cast prevents
+// LLVM from optimizing away the branch. This is likely a bug in
+// lib/CodeGen/TargetInfo.cpp with how we classify memptr types for returns.
+//
+// CHECK: define dso_local i32 @"?convertMultipleFuncToB2@@YAP8B2@@AEXXZP8Multiple@@AEXXZ@Z"{{.*}} {
+// CHECK: store
+// CHECK: %[[src:.*]] = load { i8*, i32 }, { i8*, i32 }* %{{.*}}, align 4
+// CHECK: extractvalue { i8*, i32 } %[[src]], 0
+// CHECK: icmp ne i8* %{{.*}}, null
+// CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}
+//
+// memptr.convert: ; preds = %entry
+// CHECK: %[[fp:.*]] = extractvalue { i8*, i32 } %[[src]], 0
+// CHECK: br label
+//
+// memptr.converted: ; preds = %memptr.convert, %entry
+// CHECK: phi i8* [ null, %{{.*}} ], [ %[[fp]], %{{.*}} ]
+// CHECK: }
+}
+
+namespace Test1 {
+
+struct A { int a; };
+struct B { int b; };
+struct C : virtual A { int c; };
+struct D : B, C { int d; };
+
+void (D::*convertCToD(void (C::*mp)()))() {
+ return mp;
+// CHECK: define dso_local void @"?convertCToD@Test1@@YAP8D@1@AEXXZP8C@1@AEXXZ@Z"{{.*}} {
+// CHECK: store
+// CHECK: load { i8*, i32, i32 }, { i8*, i32, i32 }* %{{.*}}, align 4
+// CHECK: extractvalue { i8*, i32, i32 } %{{.*}}, 0
+// CHECK: icmp ne i8* %{{.*}}, null
+// CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}
+//
+// memptr.convert: ; preds = %entry
+// CHECK: extractvalue { i8*, i32, i32 } %{{.*}}, 0
+// CHECK: %[[nvoff:.*]] = extractvalue { i8*, i32, i32 } %{{.*}}, 1
+// CHECK: %[[vbidx:.*]] = extractvalue { i8*, i32, i32 } %{{.*}}, 2
+// CHECK: %[[is_nvbase:.*]] = icmp eq i32 %[[vbidx]], 0
+// CHECK: %[[nv_disp:.*]] = add nsw i32 %[[nvoff]], 4
+// CHECK: %[[nv_adj:.*]] = select i1 %[[is_nvbase]], i32 %[[nv_disp]], i32 0
+// CHECK: %[[dst_adj:.*]] = select i1 %[[is_nvbase]], i32 4, i32 0
+// CHECK: %[[adj:.*]] = sub nsw i32 %[[nv_adj]], %[[dst_adj]]
+// CHECK: insertvalue { i8*, i32, i32 } undef, i8* {{.*}}, 0
+// CHECK: insertvalue { i8*, i32, i32 } {{.*}}, i32 %[[adj]], 1
+// CHECK: insertvalue { i8*, i32, i32 } {{.*}}, i32 {{.*}}, 2
+// CHECK: br label
+//
+// memptr.converted: ; preds = %memptr.convert, %entry
+// CHECK: phi { i8*, i32, i32 } [ { i8* null, i32 0, i32 -1 }, {{.*}} ], [ {{.*}} ]
+// CHECK: }
+}
+
+}
+
+namespace Test2 {
+// Test that we dynamically convert between different null reps.
+
+struct A { int a; };
+struct B : A { int b; };
+struct C : A {
+ int c;
+ virtual void hasVfPtr();
+};
+
+int A::*reinterpret(int B::*mp) {
+ return reinterpret_cast<int A::*>(mp);
+// CHECK: define dso_local i32 @"?reinterpret@Test2@@YAPQA@1@HPQB@1@H@Z"{{.*}} {
+// CHECK-NOT: select
+// CHECK: ret i32
+// CHECK: }
+}
+
+int A::*reinterpret(int C::*mp) {
+ return reinterpret_cast<int A::*>(mp);
+// CHECK: define dso_local i32 @"?reinterpret@Test2@@YAPQA@1@HPQC@1@H@Z"{{.*}} {
+// CHECK: %[[mp:.*]] = load i32, i32*
+// CHECK: %[[cmp:.*]] = icmp ne i32 %[[mp]], 0
+// CHECK: select i1 %[[cmp]], i32 %[[mp]], i32 -1
+// CHECK: }
+}
+
+}
+
+namespace Test3 {
+// Make sure we cast 'this' to i8* before using GEP.
+
+struct A {
+ int a;
+ int b;
+};
+
+int *load_data(A *a, int A::*mp) {
+ return &(a->*mp);
+// CHECK-LABEL: define dso_local i32* @"?load_data@Test3@@YAPAHPAUA@1@PQ21@H@Z"{{.*}} {
+// CHECK: %[[a:.*]] = load %"struct.Test3::A"*, %"struct.Test3::A"** %{{.*}}, align 4
+// CHECK: %[[mp:.*]] = load i32, i32* %{{.*}}, align 4
+// CHECK: %[[a_i8:.*]] = bitcast %"struct.Test3::A"* %[[a]] to i8*
+// CHECK: getelementptr inbounds i8, i8* %[[a_i8]], i32 %[[mp]]
+// CHECK: }
+}
+
+}
+
+namespace Test4 {
+
+struct A { virtual void f(); };
+struct B { virtual void g(); };
+struct C : A, B { virtual void g(); };
+
+void (C::*getmp())() {
+ return &C::g;
+}
+// CHECK-LABEL: define dso_local i64 @"?getmp@Test4@@YAP8C@1@AEXXZXZ"()
+// CHECK: store { i8*, i32 } { i8* bitcast (void (%"struct.Test4::C"*, ...)* @"??_9C@Test4@@$BA@AE" to i8*), i32 4 }, { i8*, i32 }* %{{.*}}
+//
+
+// CHECK-LABEL: define linkonce_odr x86_thiscallcc void @"??_9C@Test4@@$BA@AE"(%"struct.Test4::C"* %this, ...) {{.*}} comdat
+// CHECK-NOT: getelementptr
+// CHECK: load void (%"struct.Test4::C"*, ...)**, void (%"struct.Test4::C"*, ...)*** %{{.*}}
+// CHECK: getelementptr inbounds void (%"struct.Test4::C"*, ...)*, void (%"struct.Test4::C"*, ...)** %{{.*}}, i64 0
+// CHECK-NOT: getelementptr
+// CHECK: musttail call x86_thiscallcc void (%"struct.Test4::C"*, ...) %
+
+}
+
+namespace pr20007 {
+struct A {
+ void f();
+ void f(int);
+};
+struct B : public A {};
+void test() { void (B::*a)() = &B::f; }
+// CHECK-LABEL: define dso_local void @"?test@pr20007@@YAXXZ"
+// CHECK: store i8* bitcast (void (%"struct.pr20007::A"*)* @"?f@A@pr20007@@QAEXXZ" to i8*)
+}
+
+namespace pr20007_kw {
+struct A {
+ void f();
+ void f(int);
+};
+struct __single_inheritance B;
+struct B : public A {};
+void test() { void (B::*a)() = &B::f; }
+// CHECK-LABEL: define dso_local void @"?test@pr20007_kw@@YAXXZ"
+// CHECK: store i8* bitcast (void (%"struct.pr20007_kw::A"*)* @"?f@A@pr20007_kw@@QAEXXZ" to i8*)
+}
+
+namespace pr20007_pragma {
+struct A {
+ void f();
+ void f(int);
+};
+struct B : public A {};
+void test() { (void)(void (B::*)()) &B::f; }
+#pragma pointers_to_members(full_generality, virtual_inheritance)
+static_assert(sizeof(int B::*) == 4, "");
+static_assert(sizeof(int A::*) == 4, "");
+#pragma pointers_to_members(best_case)
+// CHECK-LABEL: define dso_local void @"?test@pr20007_pragma@@YAXXZ"
+}
+
+namespace pr20007_pragma2 {
+struct A {
+};
+struct B : public A {
+ void f();
+};
+void test() { (void)&B::f; }
+#pragma pointers_to_members(full_generality, virtual_inheritance)
+static_assert(sizeof(int B::*) == 4, "");
+static_assert(sizeof(int A::*) == 12, "");
+#pragma pointers_to_members(best_case)
+// CHECK-LABEL: define dso_local void @"?test@pr20007_pragma2@@YAXXZ"
+}
+
+namespace pr23823 {
+struct Base { void Method(); };
+struct Child : Base {};
+void use(void (Child::*const &)());
+void f() { use(&Child::Method); }
+#pragma pointers_to_members(full_generality, virtual_inheritance)
+static_assert(sizeof(int Base::*) == 4, "");
+static_assert(sizeof(int Child::*) == 4, "");
+#pragma pointers_to_members(best_case)
+}
+
+namespace pr19987 {
+template <typename T>
+struct S {
+ int T::*x;
+};
+
+struct U : S<U> {};
+
+static_assert(sizeof(S<U>::x) == 12, "");
+}
+
+#else
+struct __virtual_inheritance A;
+#ifdef MEMFUN
+int foo(A *a, int (A::*mp)()) {
+ return (a->*mp)(); // expected-error{{requires a complete class type}}
+}
+#else
+int foo(A *a, int A::*mp) {
+ return a->*mp; // expected-error{{requires a complete class type}}
+}
+#endif
+#endif
+
+namespace pr23878 {
+struct A { virtual void g(); };
+struct B { virtual void f(); };
+struct C : virtual B { void f(); };
+struct D : A, C {};
+
+typedef void (D::*DMemPtrTy)();
+
+// CHECK-LABEL: define dso_local void @"?get_memptr@pr23878@@YAP8D@1@AEXXZXZ"
+// CHECK: @"??_9C@pr23878@@$BA@AE" to i8*), i32 0, i32 4
+DMemPtrTy get_memptr() { return &D::f; }
+}
+
+class C {};
+
+typedef void (C::*f)();
+
+class CA : public C {
+public:
+ void OnHelp(void);
+ int OnHelp(int);
+};
+
+// CHECK-LABEL: foo_fun
+void foo_fun() {
+ // CHECK: store i8* bitcast (void (%class.CA*)* @"?OnHelp@CA@@QAEXXZ" to i8*), i8**
+ f func = (f)&CA::OnHelp;
+}
+namespace PR24703 {
+struct S;
+
+void f(int S::*&p) {}
+// CHECK-LABEL: define dso_local void @"?f@PR24703@@YAXAAPQS@1@H@Z"(
+}
+
+namespace ReferenceToMPTWithIncompleteClass {
+struct S;
+struct J;
+struct K;
+extern K *k;
+
+// CHECK-LABEL: @"?f@ReferenceToMPTWithIncompleteClass@@YAIAAPQS@1@H@Z"(
+// CHECK: ret i32 12
+unsigned f(int S::*&p) { return sizeof p; }
+
+// CHECK-LABEL: @"?g@ReferenceToMPTWithIncompleteClass@@YA_NAAPQJ@1@H0@Z"(
+bool g(int J::*&p, int J::*&q) { return p == q; }
+
+// CHECK-LABEL: @"?h@ReferenceToMPTWithIncompleteClass@@YAHAAPQK@1@H@Z"(
+int h(int K::*&p) { return k->*p; }
+}
+
+namespace PMFInTemplateArgument {
+template <class C, int (C::*M)(int)>
+void JSMethod();
+class A {
+ int printd(int);
+ void printd();
+};
+void A::printd() { JSMethod<A, &A::printd>(); }
+// CHECK-LABEL: @"??$JSMethod@VA@PMFInTemplateArgument@@$1?printd@12@AAEHH@Z@PMFInTemplateArgument@@YAXXZ"(
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-methods.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-methods.cpp
new file mode 100644
index 0000000..f4186a2
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-methods.cpp
@@ -0,0 +1,89 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
+
+class C {
+ public:
+ void simple_method() {}
+
+ void __cdecl cdecl_method() {}
+
+ void vararg_method(const char *fmt, ...) {}
+
+ static void static_method() {}
+
+ int a;
+};
+
+void call_simple_method() {
+ C instance;
+
+ instance.simple_method();
+// Make sure that the call uses the right calling convention:
+// CHECK: call x86_thiscallcc void @"?simple_method@C@@QAEXXZ"
+// CHECK: ret
+
+// Make sure that the definition uses the right calling convention:
+// CHECK: define linkonce_odr dso_local x86_thiscallcc void @"?simple_method@C@@QAEXXZ"
+// CHECK: ret
+}
+
+void call_cdecl_method() {
+ C instance;
+ instance.cdecl_method();
+// Make sure that the call uses the right calling convention:
+// CHECK: call void @"?cdecl_method@C@@QAAXXZ"
+// CHECK: ret
+
+// Make sure that the definition uses the right calling convention:
+// CHECK: define linkonce_odr dso_local void @"?cdecl_method@C@@QAAXXZ"
+// CHECK: ret
+}
+
+void call_vararg_method() {
+ C instance;
+ instance.vararg_method("Hello");
+// Make sure that the call uses the right calling convention:
+// CHECK: call void (%class.C*, i8*, ...) @"?vararg_method@C@@QAAXPBDZZ"
+// CHECK: ret
+
+// Make sure that the definition uses the right calling convention:
+// CHECK: define linkonce_odr dso_local void @"?vararg_method@C@@QAAXPBDZZ"
+}
+
+void call_static_method() {
+ C::static_method();
+// Make sure that the call uses the right calling convention:
+// CHECK: call void @"?static_method@C@@SAXXZ"
+// CHECK: ret
+
+// Make sure that the definition uses the right calling convention:
+// CHECK: define linkonce_odr dso_local void @"?static_method@C@@SAXXZ"
+}
+
+class Base {
+ public:
+ Base() {}
+ ~Base() {}
+};
+
+class Child: public Base { };
+
+void constructors() {
+ Child c;
+// Make sure that the Base constructor call in the Child constructor uses
+// the right calling convention:
+// CHECK: define linkonce_odr dso_local x86_thiscallcc %class.Child* @"??0Child@@QAE@XZ"
+// CHECK: %{{[.0-9A-Z_a-z]+}} = call x86_thiscallcc %class.Base* @"??0Base@@QAE@XZ"
+// CHECK: ret
+
+// Make sure that the Base destructor call in the Child denstructor uses
+// the right calling convention:
+// CHECK: define linkonce_odr dso_local x86_thiscallcc void @"??1Child@@QAE@XZ"
+// CHECK: call x86_thiscallcc void @"??1Base@@QAE@XZ"
+// CHECK: ret
+
+// Make sure that the Base constructor definition uses the right CC:
+// CHECK: define linkonce_odr dso_local x86_thiscallcc %class.Base* @"??0Base@@QAE@XZ"
+
+// Make sure that the Base destructor definition uses the right CC:
+// CHECK: define linkonce_odr dso_local x86_thiscallcc void @"??1Base@@QAE@XZ"
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp
new file mode 100644
index 0000000..cefbdaf
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp
@@ -0,0 +1,211 @@
+// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -mconstructor-aliases -triple=i386-pc-win32 | FileCheck %s
+
+struct Left {
+ virtual void left();
+};
+
+struct Right {
+ virtual void right();
+};
+
+struct ChildNoOverride : Left, Right {
+};
+
+struct ChildOverride : Left, Right {
+ virtual void left();
+ virtual void right();
+};
+
+extern "C" void foo(void *);
+
+void call_left_no_override(ChildNoOverride *child) {
+// CHECK-LABEL: define dso_local void @"?call_left_no_override
+// CHECK: %[[CHILD:.*]] = load %struct.ChildNoOverride
+
+ child->left();
+// Only need to cast 'this' to Left*.
+// CHECK: %[[LEFT:.*]] = bitcast %struct.ChildNoOverride* %[[CHILD]] to %struct.Left*
+// CHECK: %[[VFPTR:.*]] = bitcast %struct.Left* %[[LEFT]] to void (%struct.Left*)***
+// CHECK: %[[VFTABLE:.*]] = load void (%struct.Left*)**, void (%struct.Left*)*** %[[VFPTR]]
+// CHECK: %[[VFUN:.*]] = getelementptr inbounds void (%struct.Left*)*, void (%struct.Left*)** %[[VFTABLE]], i64 0
+// CHECK: %[[VFUN_VALUE:.*]] = load void (%struct.Left*)*, void (%struct.Left*)** %[[VFUN]]
+// CHECK: call x86_thiscallcc void %[[VFUN_VALUE]](%struct.Left* %[[LEFT]])
+// CHECK: ret
+}
+
+void ChildOverride::left() {
+// CHECK-LABEL: define dso_local x86_thiscallcc void @"?left@ChildOverride@@UAEXXZ"
+// CHECK-SAME: (%struct.ChildOverride* %[[THIS:.*]])
+//
+// No need to adjust 'this' as the ChildOverride's layout begins with Left.
+// CHECK: %[[THIS_ADDR:.*]] = alloca %struct.ChildOverride*, align 4
+// CHECK: store %struct.ChildOverride* %[[THIS]], %struct.ChildOverride** %[[THIS_ADDR]], align 4
+
+ foo(this);
+// CHECK: %[[THIS:.*]] = load %struct.ChildOverride*, %struct.ChildOverride** %[[THIS_ADDR]]
+// CHECK: %[[THIS_i8:.*]] = bitcast %struct.ChildOverride* %[[THIS]] to i8*
+// CHECK: call void @foo(i8* %[[THIS_i8]])
+// CHECK: ret
+}
+
+void call_left_override(ChildOverride *child) {
+// CHECK-LABEL: define dso_local void @"?call_left_override
+// CHECK: %[[CHILD:.*]] = load %struct.ChildOverride
+
+ child->left();
+// CHECK: %[[VFPTR:.*]] = bitcast %struct.ChildOverride* %[[CHILD]] to void (%struct.ChildOverride*)***
+// CHECK: %[[VFTABLE:.*]] = load void (%struct.ChildOverride*)**, void (%struct.ChildOverride*)*** %[[VFPTR]]
+// CHECK: %[[VFUN:.*]] = getelementptr inbounds void (%struct.ChildOverride*)*, void (%struct.ChildOverride*)** %[[VFTABLE]], i64 0
+// CHECK: %[[VFUN_VALUE:.*]] = load void (%struct.ChildOverride*)*, void (%struct.ChildOverride*)** %[[VFUN]]
+//
+// CHECK: call x86_thiscallcc void %[[VFUN_VALUE]](%struct.ChildOverride* %[[CHILD]])
+// CHECK: ret
+}
+
+void call_right_no_override(ChildNoOverride *child) {
+// CHECK-LABEL: define dso_local void @"?call_right_no_override
+// CHECK: %[[CHILD:.*]] = load %struct.ChildNoOverride
+
+ child->right();
+// When calling a right base's virtual method, one needs to adjust 'this' at
+// the caller site.
+//
+// CHECK: %[[CHILD_i8:.*]] = bitcast %struct.ChildNoOverride* %[[CHILD]] to i8*
+// CHECK: %[[RIGHT_i8:.*]] = getelementptr inbounds i8, i8* %[[CHILD_i8]], i32 4
+// CHECK: %[[RIGHT:.*]] = bitcast i8* %[[RIGHT_i8]] to %struct.Right*
+//
+// CHECK: %[[VFPTR:.*]] = bitcast %struct.Right* %[[RIGHT]] to void (%struct.Right*)***
+// CHECK: %[[VFTABLE:.*]] = load void (%struct.Right*)**, void (%struct.Right*)*** %[[VFPTR]]
+// CHECK: %[[VFUN:.*]] = getelementptr inbounds void (%struct.Right*)*, void (%struct.Right*)** %[[VFTABLE]], i64 0
+// CHECK: %[[VFUN_VALUE:.*]] = load void (%struct.Right*)*, void (%struct.Right*)** %[[VFUN]]
+// CHECK: call x86_thiscallcc void %[[VFUN_VALUE]](%struct.Right* %[[RIGHT]])
+// CHECK: ret
+}
+
+void ChildOverride::right() {
+// CHECK-LABEL: define dso_local x86_thiscallcc void @"?right@ChildOverride@@UAEXXZ"(i8*
+//
+// ChildOverride::right gets 'this' cast to Right* in ECX (i.e. this+4) so we
+// need to adjust 'this' before use.
+//
+// CHECK: %[[THIS_STORE:.*]] = alloca %struct.ChildOverride*, align 4
+// CHECK: %[[THIS_ADDR:.*]] = alloca %struct.ChildOverride*, align 4
+// CHECK: %[[COERCE_VAL:.*]] = bitcast i8* %[[ECX:.*]] to %struct.ChildOverride*
+// CHECK: store %struct.ChildOverride* %[[COERCE_VAL]], %struct.ChildOverride** %[[THIS_STORE]], align 4
+// CHECK: %[[THIS_INIT:.*]] = load %struct.ChildOverride*, %struct.ChildOverride** %[[THIS_STORE]], align 4
+// CHECK: store %struct.ChildOverride* %[[THIS_INIT]], %struct.ChildOverride** %[[THIS_ADDR]], align 4
+// CHECK: %[[THIS_RELOAD:.*]] = load %struct.ChildOverride*, %struct.ChildOverride** %[[THIS_ADDR]]
+// CHECK: %[[THIS_i8:.*]] = bitcast %struct.ChildOverride* %[[THIS_RELOAD]] to i8*
+// CHECK: %[[THIS_ADJUSTED:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 -4
+// CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_ADJUSTED]] to %struct.ChildOverride*
+
+ foo(this);
+// CHECK: %[[THIS_PARAM:.*]] = bitcast %struct.ChildOverride* %[[THIS]] to i8*
+// CHECK: call void @foo(i8* %[[THIS_PARAM]])
+// CHECK: ret
+}
+
+void call_right_override(ChildOverride *child) {
+// CHECK-LABEL: define dso_local void @"?call_right_override
+// CHECK: %[[CHILD:.*]] = load %struct.ChildOverride
+
+ child->right();
+// When calling a right child's virtual method, one needs to adjust 'this' at
+// the caller site.
+//
+// CHECK: %[[CHILD_i8:.*]] = bitcast %struct.ChildOverride* %[[CHILD]] to i8*
+// CHECK: %[[RIGHT:.*]] = getelementptr inbounds i8, i8* %[[CHILD_i8]], i32 4
+//
+// CHECK: %[[CHILD_i8:.*]] = bitcast %struct.ChildOverride* %[[CHILD]] to i8*
+// CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8, i8* %[[CHILD_i8]], i32 4
+// CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to void (i8*)***
+// CHECK: %[[VFTABLE:.*]] = load void (i8*)**, void (i8*)*** %[[VFPTR]]
+// CHECK: %[[VFUN:.*]] = getelementptr inbounds void (i8*)*, void (i8*)** %[[VFTABLE]], i64 0
+// CHECK: %[[VFUN_VALUE:.*]] = load void (i8*)*, void (i8*)** %[[VFUN]]
+//
+// CHECK: call x86_thiscallcc void %[[VFUN_VALUE]](i8* %[[RIGHT]])
+// CHECK: ret
+}
+
+struct GrandchildOverride : ChildOverride {
+ virtual void right();
+};
+
+void GrandchildOverride::right() {
+// CHECK-LABEL: define dso_local x86_thiscallcc void @"?right@GrandchildOverride@@UAEXXZ"(i8*
+//
+// CHECK: %[[THIS_STORE:.*]] = alloca %struct.GrandchildOverride*, align 4
+// CHECK: %[[THIS_ADDR:.*]] = alloca %struct.GrandchildOverride*, align 4
+// CHECK: %[[COERCE_VAL:.*]] = bitcast i8* %[[ECX:.*]] to %struct.GrandchildOverride*
+// CHECK: store %struct.GrandchildOverride* %[[COERCE_VAL]], %struct.GrandchildOverride** %[[THIS_STORE]], align 4
+// CHECK: %[[THIS_INIT:.*]] = load %struct.GrandchildOverride*, %struct.GrandchildOverride** %[[THIS_STORE]], align 4
+// CHECK: store %struct.GrandchildOverride* %[[THIS_INIT]], %struct.GrandchildOverride** %[[THIS_ADDR]], align 4
+// CHECK: %[[THIS_RELOAD:.*]] = load %struct.GrandchildOverride*, %struct.GrandchildOverride** %[[THIS_ADDR]]
+// CHECK: %[[THIS_i8:.*]] = bitcast %struct.GrandchildOverride* %[[THIS_RELOAD]] to i8*
+// CHECK: %[[THIS_ADJUSTED:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 -4
+// CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_ADJUSTED]] to %struct.GrandchildOverride*
+
+ foo(this);
+// CHECK: %[[THIS_PARAM:.*]] = bitcast %struct.GrandchildOverride* %[[THIS]] to i8*
+// CHECK: call void @foo(i8* %[[THIS_PARAM]])
+// CHECK: ret
+}
+
+void call_grandchild_right(GrandchildOverride *obj) {
+ // Just make sure we don't crash.
+ obj->right();
+}
+
+void emit_ctors() {
+ Left l;
+ // CHECK-LABEL: define {{.*}} @"??0Left@@QAE@XZ"
+ // CHECK-NOT: getelementptr
+ // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"??_7Left@@6B@" to i32 (...)**)
+ // CHECK: ret
+
+ Right r;
+ // CHECK-LABEL: define {{.*}} @"??0Right@@QAE@XZ"
+ // CHECK-NOT: getelementptr
+ // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"??_7Right@@6B@" to i32 (...)**)
+ // CHECK: ret
+
+ ChildOverride co;
+ // CHECK-LABEL: define {{.*}} @"??0ChildOverride@@QAE@XZ"
+ // CHECK: %[[THIS:.*]] = load %struct.ChildOverride*, %struct.ChildOverride**
+ // CHECK: %[[VFPTR:.*]] = bitcast %struct.ChildOverride* %[[THIS]] to i32 (...)***
+ // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"??_7ChildOverride@@6BLeft@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
+ // CHECK: %[[THIS_i8:.*]] = bitcast %struct.ChildOverride* %[[THIS]] to i8*
+ // CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 4
+ // CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to i32 (...)***
+ // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"??_7ChildOverride@@6BRight@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
+ // CHECK: ret
+
+ GrandchildOverride gc;
+ // CHECK-LABEL: define {{.*}} @"??0GrandchildOverride@@QAE@XZ"
+ // CHECK: %[[THIS:.*]] = load %struct.GrandchildOverride*, %struct.GrandchildOverride**
+ // CHECK: %[[VFPTR:.*]] = bitcast %struct.GrandchildOverride* %[[THIS]] to i32 (...)***
+ // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"??_7GrandchildOverride@@6BLeft@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
+ // CHECK: %[[THIS_i8:.*]] = bitcast %struct.GrandchildOverride* %[[THIS]] to i8*
+ // CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 4
+ // CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to i32 (...)***
+ // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"??_7GrandchildOverride@@6BRight@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
+ // CHECK: ret
+}
+
+struct LeftWithNonVirtualDtor {
+ virtual void left();
+ ~LeftWithNonVirtualDtor();
+};
+
+struct AsymmetricChild : LeftWithNonVirtualDtor, Right {
+ virtual ~AsymmetricChild();
+};
+
+void call_asymmetric_child_complete_dtor() {
+ // CHECK-LABEL: define dso_local void @"?call_asymmetric_child_complete_dtor@@YAXXZ"
+ AsymmetricChild obj;
+ // CHECK: call x86_thiscallcc %struct.AsymmetricChild* @"??0AsymmetricChild@@QAE@XZ"(%struct.AsymmetricChild* %[[OBJ:.*]])
+ // CHECK-NOT: getelementptr
+ // CHECK: call x86_thiscallcc void @"??1AsymmetricChild@@UAE@XZ"(%struct.AsymmetricChild* %[[OBJ]])
+ // CHECK: ret
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-non-virtual-base-ordering.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-non-virtual-base-ordering.cpp
new file mode 100644
index 0000000..0c82ac3
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-non-virtual-base-ordering.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fno-rtti -emit-llvm -triple=i686-pc-win32 -o - %s 2>/dev/null | FileCheck %s
+// RUN: %clang_cc1 -fno-rtti -emit-llvm -triple=x86_64-pc-win32 -o - %s 2>/dev/null | FileCheck %s
+
+struct C0 { int a; };
+struct C1 { int a; virtual void C1M() {} };
+struct C2 { int a; virtual void C2M() {} };
+struct C3 : C0, C1, C2 {} a;
+
+// Check to see that both C1 and C2 get laid out before C0 does.
+// CHECK: %struct.C3 = type { %struct.C1, %struct.C2, %struct.C0 }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-nontrivial-covariant-thunk.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-nontrivial-covariant-thunk.cpp
new file mode 100644
index 0000000..cb8b522
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-nontrivial-covariant-thunk.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 %s -fno-rtti -emit-llvm-only -o - -triple=i386-pc-win32 -verify
+
+// A is not trivially copyable and must be passed indirectly or with inalloca.
+struct A {
+ A();
+ A(const A &o);
+ virtual ~A();
+ int a;
+};
+
+struct B {
+ B();
+ int b;
+ virtual B *clone(A);
+};
+
+// Converting from C* to B* requires a this adjustment.
+struct C : A, B {
+ C();
+ int c;
+ virtual C *clone(A); // expected-error {{cannot compile this non-trivial argument copy for return-adjusting thunk yet}}
+};
+B::B() {} // force emission
+C::C() {} // force emission
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-rtti.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-rtti.cpp
new file mode 100644
index 0000000..a9ec5f3
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-rtti.cpp
@@ -0,0 +1,267 @@
+// RUN: %clang_cc1 -emit-llvm -o - -triple=i386-pc-win32 2>/dev/null %s | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -o - -triple=x86_64-pc-win32 2>/dev/null %s | FileCheck --check-prefix=X64 %s
+
+struct N {};
+struct M : private N {};
+struct X { virtual void f() {} };
+class Z { virtual void f() {} };
+class V : public X { virtual void f() {} };
+class W : M, virtual V { public: virtual void f() {} };
+class Y : Z, W, virtual V { public: virtual void g() {} } y;
+
+struct A {};
+struct B : A {};
+struct C : B { virtual void f() {} } c;
+
+struct X1 { virtual void f() {} };
+struct V1 : X1 {};
+struct W1 : virtual V1 {};
+struct Y1 : W1, virtual V1 {} y1;
+
+struct A1 { virtual void f() {} };
+struct B1 : virtual A1 { virtual void f() {} B1() {} } b1;
+
+struct Z2 { virtual void f() {} };
+struct Y2 { virtual void f() {} };
+struct A2 : Z2, Y2 {};
+struct B2 : virtual A2 { B2() {} virtual void f() {} } b2;
+
+// CHECK-DAG: @"??_R4B2@@6BZ2@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 8, i32 4, i8* bitcast (%rtti.TypeDescriptor8* @"??_R0?AUB2@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"??_R3B2@@8" }, comdat
+// CHECK-DAG: @"??_R0?AUB2@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"??_7type_info@@6B@", i8* null, [9 x i8] c".?AUB2@@\00" }, comdat
+// CHECK-DAG: @"??_R3B2@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 3, i32 4, %rtti.BaseClassDescriptor** getelementptr inbounds ([5 x %rtti.BaseClassDescriptor*], [5 x %rtti.BaseClassDescriptor*]* @"??_R2B2@@8", i32 0, i32 0) }, comdat
+// CHECK-DAG: @"??_R2B2@@8" = linkonce_odr constant [5 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@B2@@8", %rtti.BaseClassDescriptor* @"??_R1A@A@3FA@A2@@8", %rtti.BaseClassDescriptor* @"??_R1A@A@3EA@Z2@@8", %rtti.BaseClassDescriptor* @"??_R13A@3EA@Y2@@8", %rtti.BaseClassDescriptor* null], comdat
+// CHECK-DAG: @"??_R1A@?0A@EA@B2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"??_R0?AUB2@@@8" to i8*), i32 3, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"??_R3B2@@8" }, comdat
+// CHECK-DAG: @"??_R1A@A@3FA@A2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"??_R0?AUA2@@@8" to i8*), i32 2, i32 0, i32 0, i32 4, i32 80, %rtti.ClassHierarchyDescriptor* @"??_R3A2@@8" }, comdat
+// CHECK-DAG: @"??_R0?AUA2@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"??_7type_info@@6B@", i8* null, [9 x i8] c".?AUA2@@\00" }, comdat
+// CHECK-DAG: @"??_R3A2@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 1, i32 3, %rtti.BaseClassDescriptor** getelementptr inbounds ([4 x %rtti.BaseClassDescriptor*], [4 x %rtti.BaseClassDescriptor*]* @"??_R2A2@@8", i32 0, i32 0) }, comdat
+// CHECK-DAG: @"??_R2A2@@8" = linkonce_odr constant [4 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@A2@@8", %rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@Z2@@8", %rtti.BaseClassDescriptor* @"??_R13?0A@EA@Y2@@8", %rtti.BaseClassDescriptor* null], comdat
+// CHECK-DAG: @"??_R1A@?0A@EA@A2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"??_R0?AUA2@@@8" to i8*), i32 2, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"??_R3A2@@8" }, comdat
+// CHECK-DAG: @"??_R1A@?0A@EA@Z2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"??_R0?AUZ2@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"??_R3Z2@@8" }, comdat
+// CHECK-DAG: @"??_R0?AUZ2@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"??_7type_info@@6B@", i8* null, [9 x i8] c".?AUZ2@@\00" }, comdat
+// CHECK-DAG: @"??_R3Z2@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, %rtti.BaseClassDescriptor** getelementptr inbounds ([2 x %rtti.BaseClassDescriptor*], [2 x %rtti.BaseClassDescriptor*]* @"??_R2Z2@@8", i32 0, i32 0) }, comdat
+// CHECK-DAG: @"??_R2Z2@@8" = linkonce_odr constant [2 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@Z2@@8", %rtti.BaseClassDescriptor* null], comdat
+// CHECK-DAG: @"??_R13?0A@EA@Y2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"??_R0?AUY2@@@8" to i8*), i32 0, i32 4, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"??_R3Y2@@8" }, comdat
+// CHECK-DAG: @"??_R0?AUY2@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"??_7type_info@@6B@", i8* null, [9 x i8] c".?AUY2@@\00" }, comdat
+// CHECK-DAG: @"??_R3Y2@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, %rtti.BaseClassDescriptor** getelementptr inbounds ([2 x %rtti.BaseClassDescriptor*], [2 x %rtti.BaseClassDescriptor*]* @"??_R2Y2@@8", i32 0, i32 0) }, comdat
+// CHECK-DAG: @"??_R2Y2@@8" = linkonce_odr constant [2 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@Y2@@8", %rtti.BaseClassDescriptor* null], comdat
+// CHECK-DAG: @"??_R1A@?0A@EA@Y2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"??_R0?AUY2@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"??_R3Y2@@8" }, comdat
+// CHECK-DAG: @"??_R1A@A@3EA@Z2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"??_R0?AUZ2@@@8" to i8*), i32 0, i32 0, i32 0, i32 4, i32 64, %rtti.ClassHierarchyDescriptor* @"??_R3Z2@@8" }, comdat
+// CHECK-DAG: @"??_R13A@3EA@Y2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"??_R0?AUY2@@@8" to i8*), i32 0, i32 4, i32 0, i32 4, i32 64, %rtti.ClassHierarchyDescriptor* @"??_R3Y2@@8" }, comdat
+// CHECK-DAG: @"??_R4B2@@6BY2@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 12, i32 8, i8* bitcast (%rtti.TypeDescriptor8* @"??_R0?AUB2@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"??_R3B2@@8" }, comdat
+// CHECK-DAG: @"??_R4A2@@6BZ2@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor8* @"??_R0?AUA2@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"??_R3A2@@8" }, comdat
+// CHECK-DAG: @"??_R4A2@@6BY2@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 4, i32 0, i8* bitcast (%rtti.TypeDescriptor8* @"??_R0?AUA2@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"??_R3A2@@8" }, comdat
+// CHECK-DAG: @"??_R4Y2@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor8* @"??_R0?AUY2@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"??_R3Y2@@8" }, comdat
+// CHECK-DAG: @"??_R4Z2@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor8* @"??_R0?AUZ2@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"??_R3Z2@@8" }, comdat
+// CHECK-DAG: @"??_R4B1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 8, i32 4, i8* bitcast (%rtti.TypeDescriptor8* @"??_R0?AUB1@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"??_R3B1@@8" }, comdat
+// CHECK-DAG: @"??_R0?AUB1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"??_7type_info@@6B@", i8* null, [9 x i8] c".?AUB1@@\00" }, comdat
+// CHECK-DAG: @"??_R3B1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, %rtti.BaseClassDescriptor** getelementptr inbounds ([3 x %rtti.BaseClassDescriptor*], [3 x %rtti.BaseClassDescriptor*]* @"??_R2B1@@8", i32 0, i32 0) }, comdat
+// CHECK-DAG: @"??_R2B1@@8" = linkonce_odr constant [3 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@B1@@8", %rtti.BaseClassDescriptor* @"??_R1A@A@3FA@A1@@8", %rtti.BaseClassDescriptor* null], comdat
+// CHECK-DAG: @"??_R1A@?0A@EA@B1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"??_R0?AUB1@@@8" to i8*), i32 1, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"??_R3B1@@8" }, comdat
+// CHECK-DAG: @"??_R1A@A@3FA@A1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"??_R0?AUA1@@@8" to i8*), i32 0, i32 0, i32 0, i32 4, i32 80, %rtti.ClassHierarchyDescriptor* @"??_R3A1@@8" }, comdat
+// CHECK-DAG: @"??_R0?AUA1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"??_7type_info@@6B@", i8* null, [9 x i8] c".?AUA1@@\00" }, comdat
+// CHECK-DAG: @"??_R3A1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, %rtti.BaseClassDescriptor** getelementptr inbounds ([2 x %rtti.BaseClassDescriptor*], [2 x %rtti.BaseClassDescriptor*]* @"??_R2A1@@8", i32 0, i32 0) }, comdat
+// CHECK-DAG: @"??_R2A1@@8" = linkonce_odr constant [2 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@A1@@8", %rtti.BaseClassDescriptor* null], comdat
+// CHECK-DAG: @"??_R1A@?0A@EA@A1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"??_R0?AUA1@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"??_R3A1@@8" }, comdat
+// CHECK-DAG: @"??_R4A1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor8* @"??_R0?AUA1@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"??_R3A1@@8" }, comdat
+// CHECK-DAG: @"??_R4Y1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 4, i32 0, i8* bitcast (%rtti.TypeDescriptor8* @"??_R0?AUY1@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"??_R3Y1@@8" }, comdat
+// CHECK-DAG: @"??_R0?AUY1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"??_7type_info@@6B@", i8* null, [9 x i8] c".?AUY1@@\00" }, comdat
+// CHECK-DAG: @"??_R3Y1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 3, i32 6, %rtti.BaseClassDescriptor** getelementptr inbounds ([7 x %rtti.BaseClassDescriptor*], [7 x %rtti.BaseClassDescriptor*]* @"??_R2Y1@@8", i32 0, i32 0) }, comdat
+// CHECK-DAG: @"??_R2Y1@@8" = linkonce_odr constant [7 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@Y1@@8", %rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@W1@@8", %rtti.BaseClassDescriptor* @"??_R1A@A@3FA@V1@@8", %rtti.BaseClassDescriptor* @"??_R1A@A@3EA@X1@@8", %rtti.BaseClassDescriptor* @"??_R1A@A@3FA@V1@@8", %rtti.BaseClassDescriptor* @"??_R1A@A@3EA@X1@@8", %rtti.BaseClassDescriptor* null], comdat
+// CHECK-DAG: @"??_R1A@?0A@EA@Y1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"??_R0?AUY1@@@8" to i8*), i32 5, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"??_R3Y1@@8" }, comdat
+// CHECK-DAG: @"??_R1A@?0A@EA@W1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"??_R0?AUW1@@@8" to i8*), i32 2, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"??_R3W1@@8" }, comdat
+// CHECK-DAG: @"??_R0?AUW1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"??_7type_info@@6B@", i8* null, [9 x i8] c".?AUW1@@\00" }, comdat
+// CHECK-DAG: @"??_R3W1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 3, %rtti.BaseClassDescriptor** getelementptr inbounds ([4 x %rtti.BaseClassDescriptor*], [4 x %rtti.BaseClassDescriptor*]* @"??_R2W1@@8", i32 0, i32 0) }, comdat
+// CHECK-DAG: @"??_R2W1@@8" = linkonce_odr constant [4 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@W1@@8", %rtti.BaseClassDescriptor* @"??_R1A@A@3FA@V1@@8", %rtti.BaseClassDescriptor* @"??_R1A@A@3EA@X1@@8", %rtti.BaseClassDescriptor* null], comdat
+// CHECK-DAG: @"??_R1A@A@3FA@V1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"??_R0?AUV1@@@8" to i8*), i32 1, i32 0, i32 0, i32 4, i32 80, %rtti.ClassHierarchyDescriptor* @"??_R3V1@@8" }, comdat
+// CHECK-DAG: @"??_R0?AUV1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"??_7type_info@@6B@", i8* null, [9 x i8] c".?AUV1@@\00" }, comdat
+// CHECK-DAG: @"??_R3V1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, %rtti.BaseClassDescriptor** getelementptr inbounds ([3 x %rtti.BaseClassDescriptor*], [3 x %rtti.BaseClassDescriptor*]* @"??_R2V1@@8", i32 0, i32 0) }, comdat
+// CHECK-DAG: @"??_R2V1@@8" = linkonce_odr constant [3 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@V1@@8", %rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@X1@@8", %rtti.BaseClassDescriptor* null], comdat
+// CHECK-DAG: @"??_R1A@?0A@EA@V1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"??_R0?AUV1@@@8" to i8*), i32 1, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"??_R3V1@@8" }, comdat
+// CHECK-DAG: @"??_R1A@?0A@EA@X1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"??_R0?AUX1@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"??_R3X1@@8" }, comdat
+// CHECK-DAG: @"??_R0?AUX1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"??_7type_info@@6B@", i8* null, [9 x i8] c".?AUX1@@\00" }, comdat
+// CHECK-DAG: @"??_R3X1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, %rtti.BaseClassDescriptor** getelementptr inbounds ([2 x %rtti.BaseClassDescriptor*], [2 x %rtti.BaseClassDescriptor*]* @"??_R2X1@@8", i32 0, i32 0) }, comdat
+// CHECK-DAG: @"??_R2X1@@8" = linkonce_odr constant [2 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@X1@@8", %rtti.BaseClassDescriptor* null], comdat
+// CHECK-DAG: @"??_R1A@A@3EA@X1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"??_R0?AUX1@@@8" to i8*), i32 0, i32 0, i32 0, i32 4, i32 64, %rtti.ClassHierarchyDescriptor* @"??_R3X1@@8" }, comdat
+// CHECK-DAG: @"??_R4W1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 4, i32 0, i8* bitcast (%rtti.TypeDescriptor8* @"??_R0?AUW1@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"??_R3W1@@8" }, comdat
+// CHECK-DAG: @"??_R4V1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor8* @"??_R0?AUV1@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"??_R3V1@@8" }, comdat
+// CHECK-DAG: @"??_R4X1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor8* @"??_R0?AUX1@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"??_R3X1@@8" }, comdat
+// CHECK-DAG: @"??_R4C@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUC@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"??_R3C@@8" }, comdat
+// CHECK-DAG: @"??_R0?AUC@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"??_7type_info@@6B@", i8* null, [8 x i8] c".?AUC@@\00" }, comdat
+// CHECK-DAG: @"??_R3C@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 3, %rtti.BaseClassDescriptor** getelementptr inbounds ([4 x %rtti.BaseClassDescriptor*], [4 x %rtti.BaseClassDescriptor*]* @"??_R2C@@8", i32 0, i32 0) }, comdat
+// CHECK-DAG: @"??_R2C@@8" = linkonce_odr constant [4 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@C@@8", %rtti.BaseClassDescriptor* @"??_R13?0A@EA@B@@8", %rtti.BaseClassDescriptor* @"??_R13?0A@EA@A@@8", %rtti.BaseClassDescriptor* null], comdat
+// CHECK-DAG: @"??_R1A@?0A@EA@C@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUC@@@8" to i8*), i32 2, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"??_R3C@@8" }, comdat
+// CHECK-DAG: @"??_R13?0A@EA@B@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUB@@@8" to i8*), i32 1, i32 4, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"??_R3B@@8" }, comdat
+// CHECK-DAG: @"??_R0?AUB@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"??_7type_info@@6B@", i8* null, [8 x i8] c".?AUB@@\00" }, comdat
+// CHECK-DAG: @"??_R3B@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, %rtti.BaseClassDescriptor** getelementptr inbounds ([3 x %rtti.BaseClassDescriptor*], [3 x %rtti.BaseClassDescriptor*]* @"??_R2B@@8", i32 0, i32 0) }, comdat
+// CHECK-DAG: @"??_R2B@@8" = linkonce_odr constant [3 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@B@@8", %rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@A@@8", %rtti.BaseClassDescriptor* null], comdat
+// CHECK-DAG: @"??_R1A@?0A@EA@B@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUB@@@8" to i8*), i32 1, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"??_R3B@@8" }, comdat
+// CHECK-DAG: @"??_R1A@?0A@EA@A@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUA@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"??_R3A@@8" }, comdat
+// CHECK-DAG: @"??_R0?AUA@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"??_7type_info@@6B@", i8* null, [8 x i8] c".?AUA@@\00" }, comdat
+// CHECK-DAG: @"??_R3A@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, %rtti.BaseClassDescriptor** getelementptr inbounds ([2 x %rtti.BaseClassDescriptor*], [2 x %rtti.BaseClassDescriptor*]* @"??_R2A@@8", i32 0, i32 0) }, comdat
+// CHECK-DAG: @"??_R2A@@8" = linkonce_odr constant [2 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@A@@8", %rtti.BaseClassDescriptor* null], comdat
+// CHECK-DAG: @"??_R13?0A@EA@A@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUA@@@8" to i8*), i32 0, i32 4, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"??_R3A@@8" }, comdat
+// CHECK-DAG: @"??_R4Y@@6BZ@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AVY@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"??_R3Y@@8" }, comdat
+// CHECK-DAG: @"??_R0?AVY@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"??_7type_info@@6B@", i8* null, [8 x i8] c".?AVY@@\00" }, comdat
+// CHECK-DAG: @"??_R3Y@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 3, i32 9, %rtti.BaseClassDescriptor** getelementptr inbounds ([10 x %rtti.BaseClassDescriptor*], [10 x %rtti.BaseClassDescriptor*]* @"??_R2Y@@8", i32 0, i32 0) }, comdat
+// CHECK-DAG: @"??_R2Y@@8" = linkonce_odr constant [10 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@Y@@8", %rtti.BaseClassDescriptor* @"??_R1A@?0A@EN@Z@@8", %rtti.BaseClassDescriptor* @"??_R13?0A@EN@W@@8", %rtti.BaseClassDescriptor* @"??_R17?0A@EN@M@@8", %rtti.BaseClassDescriptor* @"??_R17?0A@EN@N@@8", %rtti.BaseClassDescriptor* @"??_R1A@33FN@V@@8", %rtti.BaseClassDescriptor* @"??_R1A@33EJ@X@@8", %rtti.BaseClassDescriptor* @"??_R1A@33FN@V@@8", %rtti.BaseClassDescriptor* @"??_R1A@33EJ@X@@8", %rtti.BaseClassDescriptor* null], comdat
+// CHECK-DAG: @"??_R1A@?0A@EA@Y@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AVY@@@8" to i8*), i32 8, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"??_R3Y@@8" }, comdat
+// CHECK-DAG: @"??_R1A@?0A@EN@Z@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AVZ@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 77, %rtti.ClassHierarchyDescriptor* @"??_R3Z@@8" }, comdat
+// CHECK-DAG: @"??_R0?AVZ@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"??_7type_info@@6B@", i8* null, [8 x i8] c".?AVZ@@\00" }, comdat
+// CHECK-DAG: @"??_R3Z@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, %rtti.BaseClassDescriptor** getelementptr inbounds ([2 x %rtti.BaseClassDescriptor*], [2 x %rtti.BaseClassDescriptor*]* @"??_R2Z@@8", i32 0, i32 0) }, comdat
+// CHECK-DAG: @"??_R2Z@@8" = linkonce_odr constant [2 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@Z@@8", %rtti.BaseClassDescriptor* null], comdat
+// CHECK-DAG: @"??_R1A@?0A@EA@Z@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AVZ@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"??_R3Z@@8" }, comdat
+// CHECK-DAG: @"??_R13?0A@EN@W@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AVW@@@8" to i8*), i32 4, i32 4, i32 -1, i32 0, i32 77, %rtti.ClassHierarchyDescriptor* @"??_R3W@@8" }, comdat
+// CHECK-DAG: @"??_R0?AVW@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"??_7type_info@@6B@", i8* null, [8 x i8] c".?AVW@@\00" }, comdat
+// CHECK-DAG: @"??_R3W@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 3, i32 5, %rtti.BaseClassDescriptor** getelementptr inbounds ([6 x %rtti.BaseClassDescriptor*], [6 x %rtti.BaseClassDescriptor*]* @"??_R2W@@8", i32 0, i32 0) }, comdat
+// CHECK-DAG: @"??_R2W@@8" = linkonce_odr constant [6 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@W@@8", %rtti.BaseClassDescriptor* @"??_R13?0A@EN@M@@8", %rtti.BaseClassDescriptor* @"??_R13?0A@EN@N@@8", %rtti.BaseClassDescriptor* @"??_R1A@A@3FN@V@@8", %rtti.BaseClassDescriptor* @"??_R1A@A@3EJ@X@@8", %rtti.BaseClassDescriptor* null], comdat
+// CHECK-DAG: @"??_R1A@?0A@EA@W@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AVW@@@8" to i8*), i32 4, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"??_R3W@@8" }, comdat
+// CHECK-DAG: @"??_R13?0A@EN@M@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUM@@@8" to i8*), i32 1, i32 4, i32 -1, i32 0, i32 77, %rtti.ClassHierarchyDescriptor* @"??_R3M@@8" }, comdat
+// CHECK-DAG: @"??_R0?AUM@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"??_7type_info@@6B@", i8* null, [8 x i8] c".?AUM@@\00" }, comdat
+// CHECK-DAG: @"??_R3M@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, %rtti.BaseClassDescriptor** getelementptr inbounds ([3 x %rtti.BaseClassDescriptor*], [3 x %rtti.BaseClassDescriptor*]* @"??_R2M@@8", i32 0, i32 0) }, comdat
+// CHECK-DAG: @"??_R2M@@8" = linkonce_odr constant [3 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@M@@8", %rtti.BaseClassDescriptor* @"??_R1A@?0A@EN@N@@8", %rtti.BaseClassDescriptor* null], comdat
+// CHECK-DAG: @"??_R1A@?0A@EA@M@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUM@@@8" to i8*), i32 1, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"??_R3M@@8" }, comdat
+// CHECK-DAG: @"??_R1A@?0A@EN@N@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUN@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 77, %rtti.ClassHierarchyDescriptor* @"??_R3N@@8" }, comdat
+// CHECK-DAG: @"??_R0?AUN@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"??_7type_info@@6B@", i8* null, [8 x i8] c".?AUN@@\00" }, comdat
+// CHECK-DAG: @"??_R3N@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, %rtti.BaseClassDescriptor** getelementptr inbounds ([2 x %rtti.BaseClassDescriptor*], [2 x %rtti.BaseClassDescriptor*]* @"??_R2N@@8", i32 0, i32 0) }, comdat
+// CHECK-DAG: @"??_R2N@@8" = linkonce_odr constant [2 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@N@@8", %rtti.BaseClassDescriptor* null], comdat
+// CHECK-DAG: @"??_R1A@?0A@EA@N@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUN@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"??_R3N@@8" }, comdat
+// CHECK-DAG: @"??_R13?0A@EN@N@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUN@@@8" to i8*), i32 0, i32 4, i32 -1, i32 0, i32 77, %rtti.ClassHierarchyDescriptor* @"??_R3N@@8" }, comdat
+// CHECK-DAG: @"??_R1A@A@3FN@V@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AVV@@@8" to i8*), i32 1, i32 0, i32 0, i32 4, i32 93, %rtti.ClassHierarchyDescriptor* @"??_R3V@@8" }, comdat
+// CHECK-DAG: @"??_R0?AVV@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"??_7type_info@@6B@", i8* null, [8 x i8] c".?AVV@@\00" }, comdat
+// CHECK-DAG: @"??_R3V@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, %rtti.BaseClassDescriptor** getelementptr inbounds ([3 x %rtti.BaseClassDescriptor*], [3 x %rtti.BaseClassDescriptor*]* @"??_R2V@@8", i32 0, i32 0) }, comdat
+// CHECK-DAG: @"??_R2V@@8" = linkonce_odr constant [3 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@V@@8", %rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@X@@8", %rtti.BaseClassDescriptor* null], comdat
+// CHECK-DAG: @"??_R1A@?0A@EA@V@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AVV@@@8" to i8*), i32 1, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"??_R3V@@8" }, comdat
+// CHECK-DAG: @"??_R1A@?0A@EA@X@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUX@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"??_R3X@@8" }, comdat
+// CHECK-DAG: @"??_R0?AUX@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"??_7type_info@@6B@", i8* null, [8 x i8] c".?AUX@@\00" }, comdat
+// CHECK-DAG: @"??_R3X@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, %rtti.BaseClassDescriptor** getelementptr inbounds ([2 x %rtti.BaseClassDescriptor*], [2 x %rtti.BaseClassDescriptor*]* @"??_R2X@@8", i32 0, i32 0) }, comdat
+// CHECK-DAG: @"??_R2X@@8" = linkonce_odr constant [2 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@X@@8", %rtti.BaseClassDescriptor* null], comdat
+// CHECK-DAG: @"??_R1A@A@3EJ@X@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUX@@@8" to i8*), i32 0, i32 0, i32 0, i32 4, i32 73, %rtti.ClassHierarchyDescriptor* @"??_R3X@@8" }, comdat
+// CHECK-DAG: @"??_R17?0A@EN@M@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUM@@@8" to i8*), i32 1, i32 8, i32 -1, i32 0, i32 77, %rtti.ClassHierarchyDescriptor* @"??_R3M@@8" }, comdat
+// CHECK-DAG: @"??_R17?0A@EN@N@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUN@@@8" to i8*), i32 0, i32 8, i32 -1, i32 0, i32 77, %rtti.ClassHierarchyDescriptor* @"??_R3N@@8" }, comdat
+// CHECK-DAG: @"??_R1A@33FN@V@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AVV@@@8" to i8*), i32 1, i32 0, i32 4, i32 4, i32 93, %rtti.ClassHierarchyDescriptor* @"??_R3V@@8" }, comdat
+// CHECK-DAG: @"??_R1A@33EJ@X@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUX@@@8" to i8*), i32 0, i32 0, i32 4, i32 4, i32 73, %rtti.ClassHierarchyDescriptor* @"??_R3X@@8" }, comdat
+// CHECK-DAG: @"??_R4Y@@6BW@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 8, i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AVY@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"??_R3Y@@8" }, comdat
+// CHECK-DAG: @"??_R4W@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 4, i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AVW@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"??_R3W@@8" }, comdat
+// CHECK-DAG: @"??_R4Z@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AVZ@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"??_R3Z@@8" }, comdat
+// CHECK-DAG: @"??_R4V@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AVV@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"??_R3V@@8" }, comdat
+// CHECK-DAG: @"??_R4X@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUX@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"??_R3X@@8" }, comdat
+
+// X64-DAG: @"??_R4B2@@6BZ2@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 16, i32 4, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"??_R0?AUB2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3B2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"??_R4B2@@6BZ2@@@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R0?AUB2@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"??_7type_info@@6B@", i8* null, [9 x i8] c".?AUB2@@\00" }, comdat
+// X64-DAG: @"??_R3B2@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 3, i32 4, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([5 x i32]* @"??_R2B2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R2B2@@8" = linkonce_odr constant [5 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@B2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1A@A@3FA@A2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1A@A@3EA@Z2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R17A@3EA@Y2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0], comdat
+// X64-DAG: @"??_R1A@?0A@EA@B2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"??_R0?AUB2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 3, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3B2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R1A@A@3FA@A2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"??_R0?AUA2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 2, i32 0, i32 0, i32 4, i32 80, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3A2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R0?AUA2@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"??_7type_info@@6B@", i8* null, [9 x i8] c".?AUA2@@\00" }, comdat
+// X64-DAG: @"??_R3A2@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 1, i32 3, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([4 x i32]* @"??_R2A2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R2A2@@8" = linkonce_odr constant [4 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@A2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@Z2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R17?0A@EA@Y2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0], comdat
+// X64-DAG: @"??_R1A@?0A@EA@A2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"??_R0?AUA2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 2, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3A2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R1A@?0A@EA@Z2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"??_R0?AUZ2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3Z2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R0?AUZ2@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"??_7type_info@@6B@", i8* null, [9 x i8] c".?AUZ2@@\00" }, comdat
+// X64-DAG: @"??_R3Z2@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([2 x i32]* @"??_R2Z2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R2Z2@@8" = linkonce_odr constant [2 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@Z2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0], comdat
+// X64-DAG: @"??_R17?0A@EA@Y2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"??_R0?AUY2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 8, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3Y2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R0?AUY2@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"??_7type_info@@6B@", i8* null, [9 x i8] c".?AUY2@@\00" }, comdat
+// X64-DAG: @"??_R3Y2@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([2 x i32]* @"??_R2Y2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R2Y2@@8" = linkonce_odr constant [2 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@Y2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0], comdat
+// X64-DAG: @"??_R1A@?0A@EA@Y2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"??_R0?AUY2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3Y2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R1A@A@3EA@Z2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"??_R0?AUZ2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 0, i32 4, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3Z2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R17A@3EA@Y2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"??_R0?AUY2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 8, i32 0, i32 4, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3Y2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R4B2@@6BY2@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 24, i32 12, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"??_R0?AUB2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3B2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"??_R4B2@@6BY2@@@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R4A2@@6BZ2@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"??_R0?AUA2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3A2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"??_R4A2@@6BZ2@@@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R4A2@@6BY2@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 8, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"??_R0?AUA2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3A2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"??_R4A2@@6BY2@@@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R4Y2@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"??_R0?AUY2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3Y2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"??_R4Y2@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R4Z2@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"??_R0?AUZ2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3Z2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"??_R4Z2@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R4B1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 16, i32 4, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"??_R0?AUB1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3B1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"??_R4B1@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R0?AUB1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"??_7type_info@@6B@", i8* null, [9 x i8] c".?AUB1@@\00" }, comdat
+// X64-DAG: @"??_R3B1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([3 x i32]* @"??_R2B1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R2B1@@8" = linkonce_odr constant [3 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@B1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1A@A@3FA@A1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0], comdat
+// X64-DAG: @"??_R1A@?0A@EA@B1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"??_R0?AUB1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3B1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R1A@A@3FA@A1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"??_R0?AUA1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 0, i32 4, i32 80, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3A1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R0?AUA1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"??_7type_info@@6B@", i8* null, [9 x i8] c".?AUA1@@\00" }, comdat
+// X64-DAG: @"??_R3A1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([2 x i32]* @"??_R2A1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R2A1@@8" = linkonce_odr constant [2 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@A1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0], comdat
+// X64-DAG: @"??_R1A@?0A@EA@A1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"??_R0?AUA1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3A1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R4A1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"??_R0?AUA1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3A1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"??_R4A1@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R4Y1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 8, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"??_R0?AUY1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3Y1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"??_R4Y1@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R0?AUY1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"??_7type_info@@6B@", i8* null, [9 x i8] c".?AUY1@@\00" }, comdat
+// X64-DAG: @"??_R3Y1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 3, i32 6, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([7 x i32]* @"??_R2Y1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R2Y1@@8" = linkonce_odr constant [7 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@Y1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@W1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1A@A@3FA@V1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1A@A@3EA@X1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1A@A@3FA@V1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1A@A@3EA@X1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0], comdat
+// X64-DAG: @"??_R1A@?0A@EA@Y1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"??_R0?AUY1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 5, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3Y1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R1A@?0A@EA@W1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"??_R0?AUW1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 2, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3W1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R0?AUW1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"??_7type_info@@6B@", i8* null, [9 x i8] c".?AUW1@@\00" }, comdat
+// X64-DAG: @"??_R3W1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 3, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([4 x i32]* @"??_R2W1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R2W1@@8" = linkonce_odr constant [4 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@W1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1A@A@3FA@V1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1A@A@3EA@X1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0], comdat
+// X64-DAG: @"??_R1A@A@3FA@V1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"??_R0?AUV1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 0, i32 0, i32 4, i32 80, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3V1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R0?AUV1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"??_7type_info@@6B@", i8* null, [9 x i8] c".?AUV1@@\00" }, comdat
+// X64-DAG: @"??_R3V1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([3 x i32]* @"??_R2V1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R2V1@@8" = linkonce_odr constant [3 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@V1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@X1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0], comdat
+// X64-DAG: @"??_R1A@?0A@EA@V1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"??_R0?AUV1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3V1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R1A@?0A@EA@X1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"??_R0?AUX1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3X1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R0?AUX1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"??_7type_info@@6B@", i8* null, [9 x i8] c".?AUX1@@\00" }, comdat
+// X64-DAG: @"??_R3X1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([2 x i32]* @"??_R2X1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R2X1@@8" = linkonce_odr constant [2 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@X1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0], comdat
+// X64-DAG: @"??_R1A@A@3EA@X1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"??_R0?AUX1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 0, i32 4, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3X1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R4W1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 8, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"??_R0?AUW1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3W1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"??_R4W1@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R4V1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"??_R0?AUV1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3V1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"??_R4V1@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R4X1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"??_R0?AUX1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3X1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"??_R4X1@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R4C@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"??_R0?AUC@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3C@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"??_R4C@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R0?AUC@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"??_7type_info@@6B@", i8* null, [8 x i8] c".?AUC@@\00" }, comdat
+// X64-DAG: @"??_R3C@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 3, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([4 x i32]* @"??_R2C@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R2C@@8" = linkonce_odr constant [4 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@C@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R17?0A@EA@B@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R17?0A@EA@A@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0], comdat
+// X64-DAG: @"??_R1A@?0A@EA@C@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"??_R0?AUC@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 2, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3C@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R17?0A@EA@B@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"??_R0?AUB@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 8, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3B@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R0?AUB@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"??_7type_info@@6B@", i8* null, [8 x i8] c".?AUB@@\00" }, comdat
+// X64-DAG: @"??_R3B@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([3 x i32]* @"??_R2B@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R2B@@8" = linkonce_odr constant [3 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@B@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@A@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0], comdat
+// X64-DAG: @"??_R1A@?0A@EA@B@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"??_R0?AUB@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3B@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R1A@?0A@EA@A@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"??_R0?AUA@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3A@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R0?AUA@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"??_7type_info@@6B@", i8* null, [8 x i8] c".?AUA@@\00" }, comdat
+// X64-DAG: @"??_R3A@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([2 x i32]* @"??_R2A@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R2A@@8" = linkonce_odr constant [2 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@A@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0], comdat
+// X64-DAG: @"??_R17?0A@EA@A@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"??_R0?AUA@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 8, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3A@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R4Y@@6BZ@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"??_R0?AVY@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3Y@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"??_R4Y@@6BZ@@@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R0?AVY@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"??_7type_info@@6B@", i8* null, [8 x i8] c".?AVY@@\00" }, comdat
+// X64-DAG: @"??_R3Y@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 3, i32 9, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([10 x i32]* @"??_R2Y@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R2Y@@8" = linkonce_odr constant [10 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@Y@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1A@?0A@EN@Z@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R17?0A@EN@W@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1BA@?0A@EN@M@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1BA@?0A@EN@N@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1A@73FN@V@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1A@73EJ@X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1A@73FN@V@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1A@73EJ@X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0], comdat
+// X64-DAG: @"??_R1A@?0A@EA@Y@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"??_R0?AVY@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 8, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3Y@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R1A@?0A@EN@Z@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"??_R0?AVZ@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 77, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3Z@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R0?AVZ@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"??_7type_info@@6B@", i8* null, [8 x i8] c".?AVZ@@\00" }, comdat
+// X64-DAG: @"??_R3Z@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([2 x i32]* @"??_R2Z@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R2Z@@8" = linkonce_odr constant [2 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@Z@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0], comdat
+// X64-DAG: @"??_R1A@?0A@EA@Z@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"??_R0?AVZ@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3Z@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R17?0A@EN@W@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"??_R0?AVW@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 4, i32 8, i32 -1, i32 0, i32 77, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3W@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R0?AVW@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"??_7type_info@@6B@", i8* null, [8 x i8] c".?AVW@@\00" }, comdat
+// X64-DAG: @"??_R3W@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 3, i32 5, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([6 x i32]* @"??_R2W@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R2W@@8" = linkonce_odr constant [6 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@W@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R17?0A@EN@M@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R17?0A@EN@N@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1A@A@3FN@V@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1A@A@3EJ@X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0], comdat
+// X64-DAG: @"??_R1A@?0A@EA@W@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"??_R0?AVW@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 4, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3W@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R17?0A@EN@M@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"??_R0?AUM@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 8, i32 -1, i32 0, i32 77, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3M@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R0?AUM@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"??_7type_info@@6B@", i8* null, [8 x i8] c".?AUM@@\00" }, comdat
+// X64-DAG: @"??_R3M@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([3 x i32]* @"??_R2M@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R2M@@8" = linkonce_odr constant [3 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@M@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1A@?0A@EN@N@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0], comdat
+// X64-DAG: @"??_R1A@?0A@EA@M@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"??_R0?AUM@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3M@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R1A@?0A@EN@N@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"??_R0?AUN@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 77, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3N@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R0?AUN@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"??_7type_info@@6B@", i8* null, [8 x i8] c".?AUN@@\00" }, comdat
+// X64-DAG: @"??_R3N@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([2 x i32]* @"??_R2N@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R2N@@8" = linkonce_odr constant [2 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@N@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0], comdat
+// X64-DAG: @"??_R1A@?0A@EA@N@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"??_R0?AUN@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3N@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R17?0A@EN@N@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"??_R0?AUN@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 8, i32 -1, i32 0, i32 77, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3N@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R1A@A@3FN@V@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"??_R0?AVV@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 0, i32 0, i32 4, i32 93, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3V@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R0?AVV@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"??_7type_info@@6B@", i8* null, [8 x i8] c".?AVV@@\00" }, comdat
+// X64-DAG: @"??_R3V@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([3 x i32]* @"??_R2V@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R2V@@8" = linkonce_odr constant [3 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@V@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0], comdat
+// X64-DAG: @"??_R1A@?0A@EA@V@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"??_R0?AVV@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3V@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R1A@?0A@EA@X@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"??_R0?AUX@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R0?AUX@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"??_7type_info@@6B@", i8* null, [8 x i8] c".?AUX@@\00" }, comdat
+// X64-DAG: @"??_R3X@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([2 x i32]* @"??_R2X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R2X@@8" = linkonce_odr constant [2 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0], comdat
+// X64-DAG: @"??_R1A@A@3EJ@X@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"??_R0?AUX@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 0, i32 4, i32 73, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R1BA@?0A@EN@M@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"??_R0?AUM@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 16, i32 -1, i32 0, i32 77, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3M@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R1BA@?0A@EN@N@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"??_R0?AUN@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 16, i32 -1, i32 0, i32 77, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3N@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R1A@73FN@V@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"??_R0?AVV@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 0, i32 8, i32 4, i32 93, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3V@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R1A@73EJ@X@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"??_R0?AUX@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 8, i32 4, i32 73, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R4Y@@6BW@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 16, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"??_R0?AVY@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3Y@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"??_R4Y@@6BW@@@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R4W@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 8, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"??_R0?AVW@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3W@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"??_R4W@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R4Z@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"??_R0?AVZ@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3Z@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"??_R4Z@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R4V@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"??_R0?AVV@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3V@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"??_R4V@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
+// X64-DAG: @"??_R4X@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"??_R0?AUX@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"??_R4X@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
new file mode 100644
index 0000000..a910a2d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
@@ -0,0 +1,443 @@
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=i386-pc-linux | FileCheck -check-prefix LINUX %s
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=i386-pc-win32 -mconstructor-aliases -fno-rtti | FileCheck -check-prefix WIN32 %s
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=thumb-pc-win32 -mconstructor-aliases -fno-rtti | FileCheck -check-prefix WOA %s
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=x86_64-pc-win32 -mconstructor-aliases -fno-rtti | FileCheck -check-prefix WIN64 %s
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=aarch64-windows-msvc -mconstructor-aliases -fno-rtti | FileCheck -check-prefix WOA64 %s
+
+struct Empty {};
+
+struct EmptyWithCtor {
+ EmptyWithCtor() {}
+};
+
+struct Small {
+ int x;
+};
+
+// This is a C++11 trivial and standard-layout struct but not a C++03 POD.
+struct SmallCpp11NotCpp03Pod : Empty {
+ int x;
+};
+
+struct SmallWithCtor {
+ SmallWithCtor() {}
+ int x;
+};
+
+struct Multibyte {
+ char a, b, c, d;
+};
+
+struct Packed {
+ short a;
+ int b;
+ short c;
+};
+
+struct SmallWithDtor {
+ SmallWithDtor();
+ ~SmallWithDtor();
+ int x;
+};
+
+struct SmallWithVftable {
+ int x;
+ virtual void foo();
+};
+
+struct Medium {
+ int x, y;
+};
+
+struct MediumWithCopyCtor {
+ MediumWithCopyCtor();
+ MediumWithCopyCtor(const struct MediumWithCopyCtor &);
+ int x, y;
+};
+
+struct Big {
+ int a, b, c, d, e, f;
+};
+
+struct BigWithDtor {
+ BigWithDtor();
+ ~BigWithDtor();
+ int a, b, c, d, e, f;
+};
+
+struct BaseNoByval : Small {
+ int bb;
+};
+
+// WIN32: declare dso_local void @"{{.*take_bools_and_chars.*}}"
+// WIN32: (<{ i8, [3 x i8], i8, [3 x i8], %struct.SmallWithDtor,
+// WIN32: i8, [3 x i8], i8, [3 x i8], i32, i8, [3 x i8] }>* inalloca)
+void take_bools_and_chars(char a, char b, SmallWithDtor c, char d, bool e, int f, bool g);
+void call_bools_and_chars() {
+ take_bools_and_chars('A', 'B', SmallWithDtor(), 'D', true, 13, false);
+}
+
+// Returning structs that fit into a register.
+Small small_return() { return Small(); }
+// LINUX-LABEL: define void @_Z12small_returnv(%struct.Small* noalias sret %agg.result)
+// WIN32: define dso_local i32 @"?small_return@@YA?AUSmall@@XZ"()
+// WIN64: define dso_local i32 @"?small_return@@YA?AUSmall@@XZ"()
+
+Medium medium_return() { return Medium(); }
+// LINUX-LABEL: define void @_Z13medium_returnv(%struct.Medium* noalias sret %agg.result)
+// WIN32: define dso_local i64 @"?medium_return@@YA?AUMedium@@XZ"()
+// WIN64: define dso_local i64 @"?medium_return@@YA?AUMedium@@XZ"()
+
+// Returning structs that fit into a register but are not POD.
+SmallCpp11NotCpp03Pod small_non_pod_return() { return SmallCpp11NotCpp03Pod(); }
+// LINUX-LABEL: define void @_Z20small_non_pod_returnv(%struct.SmallCpp11NotCpp03Pod* noalias sret %agg.result)
+// WIN32: define dso_local void @"?small_non_pod_return@@YA?AUSmallCpp11NotCpp03Pod@@XZ"(%struct.SmallCpp11NotCpp03Pod* noalias sret %agg.result)
+// WIN64: define dso_local void @"?small_non_pod_return@@YA?AUSmallCpp11NotCpp03Pod@@XZ"(%struct.SmallCpp11NotCpp03Pod* noalias sret %agg.result)
+
+SmallWithCtor small_with_ctor_return() { return SmallWithCtor(); }
+// LINUX-LABEL: define void @_Z22small_with_ctor_returnv(%struct.SmallWithCtor* noalias sret %agg.result)
+// WIN32: define dso_local void @"?small_with_ctor_return@@YA?AUSmallWithCtor@@XZ"(%struct.SmallWithCtor* noalias sret %agg.result)
+// WIN64: define dso_local void @"?small_with_ctor_return@@YA?AUSmallWithCtor@@XZ"(%struct.SmallWithCtor* noalias sret %agg.result)
+// FIXME: The 'sret' mark here doesn't seem to be enough to convince LLVM to
+// preserve the hidden sret pointer in R0 across the function.
+// WOA: define dso_local arm_aapcs_vfpcc void @"?small_with_ctor_return@@YA?AUSmallWithCtor@@XZ"(%struct.SmallWithCtor* noalias sret %agg.result)
+
+SmallWithVftable small_with_vftable_return() { return SmallWithVftable(); }
+// LINUX-LABEL: define void @_Z25small_with_vftable_returnv(%struct.SmallWithVftable* noalias sret %agg.result)
+// WIN32: define dso_local void @"?small_with_vftable_return@@YA?AUSmallWithVftable@@XZ"(%struct.SmallWithVftable* noalias sret %agg.result)
+// WIN64: define dso_local void @"?small_with_vftable_return@@YA?AUSmallWithVftable@@XZ"(%struct.SmallWithVftable* noalias sret %agg.result)
+
+MediumWithCopyCtor medium_with_copy_ctor_return() { return MediumWithCopyCtor(); }
+// LINUX-LABEL: define void @_Z28medium_with_copy_ctor_returnv(%struct.MediumWithCopyCtor* noalias sret %agg.result)
+// WIN32: define dso_local void @"?medium_with_copy_ctor_return@@YA?AUMediumWithCopyCtor@@XZ"(%struct.MediumWithCopyCtor* noalias sret %agg.result)
+// WIN64: define dso_local void @"?medium_with_copy_ctor_return@@YA?AUMediumWithCopyCtor@@XZ"(%struct.MediumWithCopyCtor* noalias sret %agg.result)
+// WOA: define dso_local arm_aapcs_vfpcc void @"?medium_with_copy_ctor_return@@YA?AUMediumWithCopyCtor@@XZ"(%struct.MediumWithCopyCtor* noalias sret %agg.result)
+
+// Returning a large struct that doesn't fit into a register.
+Big big_return() { return Big(); }
+// LINUX-LABEL: define void @_Z10big_returnv(%struct.Big* noalias sret %agg.result)
+// WIN32: define dso_local void @"?big_return@@YA?AUBig@@XZ"(%struct.Big* noalias sret %agg.result)
+// WIN64: define dso_local void @"?big_return@@YA?AUBig@@XZ"(%struct.Big* noalias sret %agg.result)
+
+
+void small_arg(Small s) {}
+// LINUX-LABEL: define void @_Z9small_arg5Small(i32 %s.0)
+// WIN32: define dso_local void @"?small_arg@@YAXUSmall@@@Z"(i32 %s.0)
+// WIN64: define dso_local void @"?small_arg@@YAXUSmall@@@Z"(i32 %s.coerce)
+// WOA: define dso_local arm_aapcs_vfpcc void @"?small_arg@@YAXUSmall@@@Z"([1 x i32] %s.coerce)
+
+void medium_arg(Medium s) {}
+// LINUX-LABEL: define void @_Z10medium_arg6Medium(i32 %s.0, i32 %s.1)
+// WIN32: define dso_local void @"?medium_arg@@YAXUMedium@@@Z"(i32 %s.0, i32 %s.1)
+// WIN64: define dso_local void @"?medium_arg@@YAXUMedium@@@Z"(i64 %s.coerce)
+// WOA: define dso_local arm_aapcs_vfpcc void @"?medium_arg@@YAXUMedium@@@Z"([2 x i32] %s.coerce)
+
+void base_no_byval_arg(BaseNoByval s) {}
+// LINUX-LABEL: define void @_Z17base_no_byval_arg11BaseNoByval(%struct.BaseNoByval* byval align 4 %s)
+// WIN32: define dso_local void @"?base_no_byval_arg@@YAXUBaseNoByval@@@Z"(i32 %s.0, i32 %s.1)
+// WIN64: define dso_local void @"?base_no_byval_arg@@YAXUBaseNoByval@@@Z"(i64 %s.coerce)
+// WOA: define dso_local arm_aapcs_vfpcc void @"?base_no_byval_arg@@YAXUBaseNoByval@@@Z"([2 x i32] %s.coerce)
+
+void small_arg_with_ctor(SmallWithCtor s) {}
+// LINUX-LABEL: define void @_Z19small_arg_with_ctor13SmallWithCtor(%struct.SmallWithCtor* byval align 4 %s)
+// WIN32: define dso_local void @"?small_arg_with_ctor@@YAXUSmallWithCtor@@@Z"(i32 %s.0)
+// WIN64: define dso_local void @"?small_arg_with_ctor@@YAXUSmallWithCtor@@@Z"(i32 %s.coerce)
+// WOA: define dso_local arm_aapcs_vfpcc void @"?small_arg_with_ctor@@YAXUSmallWithCtor@@@Z"([1 x i32] %s.coerce)
+
+// FIXME: We could coerce to a series of i32s here if we wanted to.
+void multibyte_arg(Multibyte s) {}
+// LINUX-LABEL: define void @_Z13multibyte_arg9Multibyte(%struct.Multibyte* byval align 4 %s)
+// WIN32: define dso_local void @"?multibyte_arg@@YAXUMultibyte@@@Z"(%struct.Multibyte* byval align 4 %s)
+// WIN64: define dso_local void @"?multibyte_arg@@YAXUMultibyte@@@Z"(i32 %s.coerce)
+// WOA: define dso_local arm_aapcs_vfpcc void @"?multibyte_arg@@YAXUMultibyte@@@Z"([1 x i32] %s.coerce)
+
+void packed_arg(Packed s) {}
+// LINUX-LABEL: define void @_Z10packed_arg6Packed(%struct.Packed* byval align 4 %s)
+// WIN32: define dso_local void @"?packed_arg@@YAXUPacked@@@Z"(%struct.Packed* byval align 4 %s)
+// WIN64: define dso_local void @"?packed_arg@@YAXUPacked@@@Z"(%struct.Packed* %s)
+
+// Test that dtors are invoked in the callee.
+void small_arg_with_dtor(SmallWithDtor s) {}
+// WIN32: define dso_local void @"?small_arg_with_dtor@@YAXUSmallWithDtor@@@Z"(<{ %struct.SmallWithDtor }>* inalloca) {{.*}} {
+// WIN32: call x86_thiscallcc void @"??1SmallWithDtor@@QAE@XZ"
+// WIN32: }
+// WIN64: define dso_local void @"?small_arg_with_dtor@@YAXUSmallWithDtor@@@Z"(i32 %s.coerce) {{.*}} {
+// WIN64: call void @"??1SmallWithDtor@@QEAA@XZ"
+// WIN64: }
+// WOA64: define dso_local void @"?small_arg_with_dtor@@YAXUSmallWithDtor@@@Z"(i64 %s.coerce) {{.*}} {
+// WOA64: call void @"??1SmallWithDtor@@QEAA@XZ"
+// WOA64: }
+
+// FIXME: MSVC incompatible!
+// WOA: define dso_local arm_aapcs_vfpcc void @"?small_arg_with_dtor@@YAXUSmallWithDtor@@@Z"(%struct.SmallWithDtor* %s) {{.*}} {
+// WOA: call arm_aapcs_vfpcc void @"??1SmallWithDtor@@QAA@XZ"(%struct.SmallWithDtor* %s)
+// WOA: }
+
+void call_small_arg_with_dtor() {
+ small_arg_with_dtor(SmallWithDtor());
+}
+// WIN64-LABEL: define dso_local void @"?call_small_arg_with_dtor@@YAXXZ"()
+// WIN64: call %struct.SmallWithDtor* @"??0SmallWithDtor@@QEAA@XZ"
+// WIN64: call void @"?small_arg_with_dtor@@YAXUSmallWithDtor@@@Z"(i32 %{{.*}})
+// WIN64: ret void
+
+// Test that references aren't destroyed in the callee.
+void ref_small_arg_with_dtor(const SmallWithDtor &s) { }
+// WIN32: define dso_local void @"?ref_small_arg_with_dtor@@YAXABUSmallWithDtor@@@Z"(%struct.SmallWithDtor* dereferenceable({{[0-9]+}}) %s) {{.*}} {
+// WIN32-NOT: call x86_thiscallcc void @"??1SmallWithDtor@@QAE@XZ"
+// WIN32: }
+// WIN64-LABEL: define dso_local void @"?ref_small_arg_with_dtor@@YAXAEBUSmallWithDtor@@@Z"(%struct.SmallWithDtor* dereferenceable({{[0-9]+}}) %s)
+
+void big_arg_with_dtor(BigWithDtor s) {}
+// WIN64-LABEL: define dso_local void @"?big_arg_with_dtor@@YAXUBigWithDtor@@@Z"(%struct.BigWithDtor* %s)
+// WIN64: call void @"??1BigWithDtor@@QEAA@XZ"
+// WIN64: }
+
+void call_big_arg_with_dtor() {
+ big_arg_with_dtor(BigWithDtor());
+}
+// We can elide the copy of the temporary in the caller, because this object is
+// larger than 8 bytes and is passed indirectly.
+// WIN64-LABEL: define dso_local void @"?call_big_arg_with_dtor@@YAXXZ"()
+// WIN64: call %struct.BigWithDtor* @"??0BigWithDtor@@QEAA@XZ"
+// WIN64: call void @"?big_arg_with_dtor@@YAXUBigWithDtor@@@Z"(%struct.BigWithDtor* %{{.*}})
+// WIN64-NOT: call void @"??1BigWithDtor@@QEAA@XZ"
+// WIN64: ret void
+
+// Test that temporaries passed by reference are destroyed in the caller.
+void temporary_ref_with_dtor() {
+ ref_small_arg_with_dtor(SmallWithDtor());
+}
+// WIN32: define dso_local void @"?temporary_ref_with_dtor@@YAXXZ"() {{.*}} {
+// WIN32: call x86_thiscallcc %struct.SmallWithDtor* @"??0SmallWithDtor@@QAE@XZ"
+// WIN32: call void @"?ref_small_arg_with_dtor@@YAXABUSmallWithDtor@@@Z"
+// WIN32: call x86_thiscallcc void @"??1SmallWithDtor@@QAE@XZ"
+// WIN32: }
+
+void takes_two_by_val_with_dtor(SmallWithDtor a, SmallWithDtor b);
+void eh_cleanup_arg_with_dtor() {
+ takes_two_by_val_with_dtor(SmallWithDtor(), SmallWithDtor());
+}
+// When exceptions are off, we don't have any cleanups. See
+// microsoft-abi-exceptions.cpp for these cleanups.
+// WIN32: define dso_local void @"?eh_cleanup_arg_with_dtor@@YAXXZ"() {{.*}} {
+// WIN32: call x86_thiscallcc %struct.SmallWithDtor* @"??0SmallWithDtor@@QAE@XZ"
+// WIN32: call x86_thiscallcc %struct.SmallWithDtor* @"??0SmallWithDtor@@QAE@XZ"
+// WIN32: call void @"?takes_two_by_val_with_dtor@@YAXUSmallWithDtor@@0@Z"
+// WIN32-NOT: call x86_thiscallcc void @"??1SmallWithDtor@@QAE@XZ"
+// WIN32: }
+
+void small_arg_with_vftable(SmallWithVftable s) {}
+// LINUX-LABEL: define void @_Z22small_arg_with_vftable16SmallWithVftable(%struct.SmallWithVftable* %s)
+// WIN32: define dso_local void @"?small_arg_with_vftable@@YAXUSmallWithVftable@@@Z"(<{ %struct.SmallWithVftable }>* inalloca)
+// WIN64: define dso_local void @"?small_arg_with_vftable@@YAXUSmallWithVftable@@@Z"(%struct.SmallWithVftable* %s)
+// WOA64: define dso_local void @"?small_arg_with_vftable@@YAXUSmallWithVftable@@@Z"(%struct.SmallWithVftable* %s)
+
+void medium_arg_with_copy_ctor(MediumWithCopyCtor s) {}
+// LINUX-LABEL: define void @_Z25medium_arg_with_copy_ctor18MediumWithCopyCtor(%struct.MediumWithCopyCtor* %s)
+// WIN32: define dso_local void @"?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(<{ %struct.MediumWithCopyCtor }>* inalloca)
+// WIN64: define dso_local void @"?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(%struct.MediumWithCopyCtor* %s)
+// WOA: define dso_local arm_aapcs_vfpcc void @"?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(%struct.MediumWithCopyCtor* %s)
+// WOA64: define dso_local void @"?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(%struct.MediumWithCopyCtor* %s)
+
+void big_arg(Big s) {}
+// LINUX-LABEL: define void @_Z7big_arg3Big(%struct.Big* byval align 4 %s)
+// WIN32: define dso_local void @"?big_arg@@YAXUBig@@@Z"(%struct.Big* byval align 4 %s)
+// WIN64: define dso_local void @"?big_arg@@YAXUBig@@@Z"(%struct.Big* %s)
+
+// PR27607: We would attempt to load i32 value out of the reference instead of
+// just loading the pointer from the struct during argument expansion.
+struct RefField {
+ RefField(int &x);
+ int &x;
+};
+void takes_ref_field(RefField s) {}
+// LINUX-LABEL: define void @_Z15takes_ref_field8RefField(%struct.RefField* byval align 4 %s)
+// WIN32: define dso_local void @"?takes_ref_field@@YAXURefField@@@Z"(i32* %s.0)
+// WIN64: define dso_local void @"?takes_ref_field@@YAXURefField@@@Z"(i64 %s.coerce)
+
+void pass_ref_field() {
+ int x;
+ takes_ref_field(RefField(x));
+}
+// LINUX-LABEL: define void @_Z14pass_ref_fieldv()
+// LINUX: call void @_Z15takes_ref_field8RefField(%struct.RefField* byval align 4 %{{.*}})
+// WIN32-LABEL: define dso_local void @"?pass_ref_field@@YAXXZ"()
+// WIN32: call void @"?takes_ref_field@@YAXURefField@@@Z"(i32* %{{.*}})
+// WIN64-LABEL: define dso_local void @"?pass_ref_field@@YAXXZ"()
+// WIN64: call void @"?takes_ref_field@@YAXURefField@@@Z"(i64 %{{.*}})
+
+class Class {
+ public:
+ Small thiscall_method_small() { return Small(); }
+ // LINUX: define {{.*}} void @_ZN5Class21thiscall_method_smallEv(%struct.Small* noalias sret %agg.result, %class.Class* %this)
+ // WIN32: define {{.*}} x86_thiscallcc void @"?thiscall_method_small@Class@@QAE?AUSmall@@XZ"(%class.Class* %this, %struct.Small* noalias sret %agg.result)
+ // WIN64: define linkonce_odr dso_local void @"?thiscall_method_small@Class@@QEAA?AUSmall@@XZ"(%class.Class* %this, %struct.Small* noalias sret %agg.result)
+
+ SmallWithCtor thiscall_method_small_with_ctor() { return SmallWithCtor(); }
+ // LINUX: define {{.*}} void @_ZN5Class31thiscall_method_small_with_ctorEv(%struct.SmallWithCtor* noalias sret %agg.result, %class.Class* %this)
+ // WIN32: define {{.*}} x86_thiscallcc void @"?thiscall_method_small_with_ctor@Class@@QAE?AUSmallWithCtor@@XZ"(%class.Class* %this, %struct.SmallWithCtor* noalias sret %agg.result)
+ // WIN64: define linkonce_odr dso_local void @"?thiscall_method_small_with_ctor@Class@@QEAA?AUSmallWithCtor@@XZ"(%class.Class* %this, %struct.SmallWithCtor* noalias sret %agg.result)
+
+ Small __cdecl cdecl_method_small() { return Small(); }
+ // LINUX: define {{.*}} void @_ZN5Class18cdecl_method_smallEv(%struct.Small* noalias sret %agg.result, %class.Class* %this)
+ // WIN32: define {{.*}} void @"?cdecl_method_small@Class@@QAA?AUSmall@@XZ"(%class.Class* %this, %struct.Small* noalias sret %agg.result)
+ // WIN64: define linkonce_odr dso_local void @"?cdecl_method_small@Class@@QEAA?AUSmall@@XZ"(%class.Class* %this, %struct.Small* noalias sret %agg.result)
+
+ Big __cdecl cdecl_method_big() { return Big(); }
+ // LINUX: define {{.*}} void @_ZN5Class16cdecl_method_bigEv(%struct.Big* noalias sret %agg.result, %class.Class* %this)
+ // WIN32: define {{.*}} void @"?cdecl_method_big@Class@@QAA?AUBig@@XZ"(%class.Class* %this, %struct.Big* noalias sret %agg.result)
+ // WIN64: define linkonce_odr dso_local void @"?cdecl_method_big@Class@@QEAA?AUBig@@XZ"(%class.Class* %this, %struct.Big* noalias sret %agg.result)
+
+ void thiscall_method_arg(Empty s) {}
+ // LINUX: define {{.*}} void @_ZN5Class19thiscall_method_argE5Empty(%class.Class* %this)
+ // WIN32: define {{.*}} void @"?thiscall_method_arg@Class@@QAEXUEmpty@@@Z"(%class.Class* %this, %struct.Empty* byval align 4 %s)
+ // WIN64: define linkonce_odr dso_local void @"?thiscall_method_arg@Class@@QEAAXUEmpty@@@Z"(%class.Class* %this, i8 %s.coerce)
+
+ void thiscall_method_arg(EmptyWithCtor s) {}
+ // LINUX: define {{.*}} void @_ZN5Class19thiscall_method_argE13EmptyWithCtor(%class.Class* %this)
+ // WIN32: define {{.*}} void @"?thiscall_method_arg@Class@@QAEXUEmptyWithCtor@@@Z"(%class.Class* %this, %struct.EmptyWithCtor* byval align 4 %s)
+ // WIN64: define linkonce_odr dso_local void @"?thiscall_method_arg@Class@@QEAAXUEmptyWithCtor@@@Z"(%class.Class* %this, i8 %s.coerce)
+
+ void thiscall_method_arg(Small s) {}
+ // LINUX: define {{.*}} void @_ZN5Class19thiscall_method_argE5Small(%class.Class* %this, i32 %s.0)
+ // WIN32: define {{.*}} void @"?thiscall_method_arg@Class@@QAEXUSmall@@@Z"(%class.Class* %this, i32 %s.0)
+ // WIN64: define linkonce_odr dso_local void @"?thiscall_method_arg@Class@@QEAAXUSmall@@@Z"(%class.Class* %this, i32 %s.coerce)
+
+ void thiscall_method_arg(SmallWithCtor s) {}
+ // LINUX: define {{.*}} void @_ZN5Class19thiscall_method_argE13SmallWithCtor(%class.Class* %this, %struct.SmallWithCtor* byval align 4 %s)
+ // WIN32: define {{.*}} void @"?thiscall_method_arg@Class@@QAEXUSmallWithCtor@@@Z"(%class.Class* %this, i32 %s.0)
+ // WIN64: define linkonce_odr dso_local void @"?thiscall_method_arg@Class@@QEAAXUSmallWithCtor@@@Z"(%class.Class* %this, i32 %s.coerce)
+
+ void thiscall_method_arg(Big s) {}
+ // LINUX: define {{.*}} void @_ZN5Class19thiscall_method_argE3Big(%class.Class* %this, %struct.Big* byval align 4 %s)
+ // WIN32: define {{.*}} void @"?thiscall_method_arg@Class@@QAEXUBig@@@Z"(%class.Class* %this, %struct.Big* byval align 4 %s)
+ // WIN64: define linkonce_odr dso_local void @"?thiscall_method_arg@Class@@QEAAXUBig@@@Z"(%class.Class* %this, %struct.Big* %s)
+};
+
+void use_class() {
+ Class c;
+ c.thiscall_method_small();
+ c.thiscall_method_small_with_ctor();
+
+ c.cdecl_method_small();
+ c.cdecl_method_big();
+
+ c.thiscall_method_arg(Empty());
+ c.thiscall_method_arg(EmptyWithCtor());
+ c.thiscall_method_arg(Small());
+ c.thiscall_method_arg(SmallWithCtor());
+ c.thiscall_method_arg(Big());
+}
+
+struct X {
+ X();
+ ~X();
+};
+void g(X) {
+}
+// WIN32: define dso_local void @"?g@@YAXUX@@@Z"(<{ %struct.X, [3 x i8] }>* inalloca) {{.*}} {
+// WIN32: call x86_thiscallcc void @"??1X@@QAE@XZ"(%struct.X* {{.*}})
+// WIN32: }
+void f() {
+ g(X());
+}
+// WIN32: define dso_local void @"?f@@YAXXZ"() {{.*}} {
+// WIN32-NOT: call {{.*}} @"??1X@@QAE@XZ"
+// WIN32: }
+
+
+namespace test2 {
+// We used to crash on this due to the mixture of POD byval and non-trivial
+// byval.
+
+struct NonTrivial {
+ NonTrivial();
+ NonTrivial(const NonTrivial &o);
+ ~NonTrivial();
+ int a;
+};
+struct POD { int b; };
+
+int foo(NonTrivial a, POD b);
+void bar() {
+ POD b;
+ b.b = 13;
+ int c = foo(NonTrivial(), b);
+}
+// WIN32-LABEL: define dso_local void @"?bar@test2@@YAXXZ"() {{.*}} {
+// WIN32: %[[argmem:[^ ]*]] = alloca inalloca [[argmem_ty:<{ %"struct.test2::NonTrivial", %"struct.test2::POD" }>]]
+// WIN32: getelementptr inbounds [[argmem_ty]], [[argmem_ty]]* %[[argmem]], i32 0, i32 1
+// WIN32: call void @llvm.memcpy
+// WIN32: getelementptr inbounds [[argmem_ty]], [[argmem_ty]]* %[[argmem]], i32 0, i32 0
+// WIN32: call x86_thiscallcc %"struct.test2::NonTrivial"* @"??0NonTrivial@test2@@QAE@XZ"
+// WIN32: call i32 @"?foo@test2@@YAHUNonTrivial@1@UPOD@1@@Z"([[argmem_ty]]* inalloca %argmem)
+// WIN32: ret void
+// WIN32: }
+
+}
+
+namespace test3 {
+
+// Check that we padded the inalloca struct to a multiple of 4.
+struct NonTrivial {
+ NonTrivial();
+ NonTrivial(const NonTrivial &o);
+ ~NonTrivial();
+ int a;
+};
+void foo(NonTrivial a, bool b) { }
+// WIN32-LABEL: define dso_local void @"?foo@test3@@YAXUNonTrivial@1@_N@Z"(<{ %"struct.test3::NonTrivial", i8, [3 x i8] }>* inalloca)
+
+}
+
+// We would crash here because the later definition of ForwardDeclare1 results
+// in a different IR type for the value we want to store. However, the alloca's
+// type will use the argument type selected by fn1.
+struct ForwardDeclare1;
+
+typedef void (*FnPtr1)(ForwardDeclare1);
+void fn1(FnPtr1 a, SmallWithDtor b) { }
+
+struct ForwardDeclare1 {};
+
+void fn2(FnPtr1 a, SmallWithDtor b) { fn1(a, b); };
+// WIN32-LABEL: define dso_local void @"?fn2@@YAXP6AXUForwardDeclare1@@@ZUSmallWithDtor@@@Z"
+// WIN32: %[[a:[^ ]*]] = getelementptr inbounds [[argmem_ty:<{ {}\*, %struct.SmallWithDtor }>]], [[argmem_ty:<{ {}\*, %struct.SmallWithDtor }>]]* %{{.*}}, i32 0, i32 0
+// WIN32: %[[a1:[^ ]*]] = bitcast {}** %[[a]] to void [[dst_ty:\(%struct.ForwardDeclare1\*\)\*]]*
+// WIN32: %[[argmem:[^ ]*]] = alloca inalloca [[argmem_ty]]
+// WIN32: %[[gep1:[^ ]*]] = getelementptr inbounds [[argmem_ty]], [[argmem_ty]]* %[[argmem]], i32 0, i32 1
+// WIN32: %[[bc1:[^ ]*]] = bitcast %struct.SmallWithDtor* %[[gep1]] to i8*
+// WIN32: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %[[bc1]], i8* align 4 {{.*}}, i32 4, i1 false)
+// WIN32: %[[a2:[^ ]*]] = load void [[dst_ty]], void [[dst_ty]]* %[[a1]], align 4
+// WIN32: %[[gep2:[^ ]*]] = getelementptr inbounds [[argmem_ty]], [[argmem_ty]]* %[[argmem]], i32 0, i32 0
+// WIN32: %[[addr:[^ ]*]] = bitcast {}** %[[gep2]] to void [[dst_ty]]*
+// WIN32: store void [[dst_ty]] %[[a2]], void [[dst_ty]]* %[[addr]], align 4
+// WIN32: call void @"?fn1@@YAXP6AXUForwardDeclare1@@@ZUSmallWithDtor@@@Z"([[argmem_ty]]* inalloca %[[argmem]])
+
+namespace pr30293 {
+// Virtual methods living in a secondary vtable take i8* as their 'this'
+// parameter because the 'this' parameter on entry points to the secondary
+// vptr. We used to have a bug where we didn't apply this rule consistently,
+// and it would cause assertion failures when used with inalloca.
+struct A {
+ virtual void f();
+};
+struct B {
+ virtual void __cdecl h(SmallWithDtor);
+};
+struct C final : A, B {
+ void g();
+ void __cdecl h(SmallWithDtor);
+ void f();
+};
+void C::g() { return h(SmallWithDtor()); }
+
+// WIN32-LABEL: define dso_local x86_thiscallcc void @"?g@C@pr30293@@QAEXXZ"(%"struct.pr30293::C"* %this)
+// WIN32: call x86_thiscallcc %struct.SmallWithDtor* @"??0SmallWithDtor@@QAE@XZ"
+// WIN32: call void @"?h@C@pr30293@@UAAXUSmallWithDtor@@@Z"(<{ i8*, %struct.SmallWithDtor }>* inalloca %{{[^,)]*}})
+// WIN32: declare dso_local void @"?h@C@pr30293@@UAAXUSmallWithDtor@@@Z"(<{ i8*, %struct.SmallWithDtor }>* inalloca)
+
+// WIN64-LABEL: define dso_local void @"?g@C@pr30293@@QEAAXXZ"(%"struct.pr30293::C"* %this)
+// WIN64: declare dso_local void @"?h@C@pr30293@@UEAAXUSmallWithDtor@@@Z"(i8*, i32)
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-static-initializers.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-static-initializers.cpp
new file mode 100644
index 0000000..e6a0891
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-static-initializers.cpp
@@ -0,0 +1,251 @@
+// RUN: %clang_cc1 -fms-extensions -fno-threadsafe-statics -emit-llvm %s -o - -mconstructor-aliases -triple=i386-pc-win32 | FileCheck %s
+
+// CHECK: @llvm.global_ctors = appending global [5 x { i32, void ()*, i8* }] [
+// CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @"??__Eselectany1@@YAXXZ", i8* getelementptr inbounds (%struct.S, %struct.S* @"?selectany1@@3US@@A", i32 0, i32 0) },
+// CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @"??__Eselectany2@@YAXXZ", i8* getelementptr inbounds (%struct.S, %struct.S* @"?selectany2@@3US@@A", i32 0, i32 0) },
+// CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @"??__E?s@?$ExportedTemplate@H@@2US@@A@@YAXXZ", i8* getelementptr inbounds (%struct.S, %struct.S* @"?s@?$ExportedTemplate@H@@2US@@A", i32 0, i32 0) },
+// CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @"??__E?foo@?$B@H@@2VA@@A@@YAXXZ", i8* bitcast (%class.A* @"?foo@?$B@H@@2VA@@A" to i8*) },
+// CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_microsoft_abi_static_initializers.cpp, i8* null }
+// CHECK: ]
+
+struct S {
+ S();
+ ~S();
+};
+
+S s;
+
+// CHECK: define internal void @"??__Es@@YAXXZ"()
+// CHECK: call x86_thiscallcc %struct.S* @"??0S@@QAE@XZ"
+// CHECK: call i32 @atexit(void ()* @"??__Fs@@YAXXZ")
+// CHECK: ret void
+
+// CHECK: define internal void @"??__Fs@@YAXXZ"()
+// CHECK: call x86_thiscallcc void @"??1S@@QAE@XZ"
+// CHECK: ret void
+
+// These globals should have initializers comdat associative with the global.
+// See @llvm.global_ctors above.
+__declspec(selectany) S selectany1;
+__declspec(selectany) S selectany2;
+// CHECK: define linkonce_odr dso_local void @"??__Eselectany1@@YAXXZ"() {{.*}} comdat
+// CHECK-NOT: @"??_Bselectany1
+// CHECK: call x86_thiscallcc %struct.S* @"??0S@@QAE@XZ"
+// CHECK: ret void
+// CHECK: define linkonce_odr dso_local void @"??__Eselectany2@@YAXXZ"() {{.*}} comdat
+// CHECK-NOT: @"??_Bselectany2
+// CHECK: call x86_thiscallcc %struct.S* @"??0S@@QAE@XZ"
+// CHECK: ret void
+
+// The implicitly instantiated static data member should have initializer
+// comdat associative with the global.
+template <typename T> struct __declspec(dllexport) ExportedTemplate {
+ static S s;
+};
+template <typename T> S ExportedTemplate<T>::s;
+void useExportedTemplate(ExportedTemplate<int> x) {
+ (void)x.s;
+}
+
+void StaticLocal() {
+ static S TheS;
+}
+
+// CHECK-LABEL: define dso_local void @"?StaticLocal@@YAXXZ"()
+// CHECK: load i32, i32* @"?$S1@?1??StaticLocal@@YAXXZ@4IA"
+// CHECK: store i32 {{.*}}, i32* @"?$S1@?1??StaticLocal@@YAXXZ@4IA"
+// CHECK: ret
+
+void MultipleStatics() {
+ static S S1;
+ static S S2;
+ static S S3;
+ static S S4;
+ static S S5;
+ static S S6;
+ static S S7;
+ static S S8;
+ static S S9;
+ static S S10;
+ static S S11;
+ static S S12;
+ static S S13;
+ static S S14;
+ static S S15;
+ static S S16;
+ static S S17;
+ static S S18;
+ static S S19;
+ static S S20;
+ static S S21;
+ static S S22;
+ static S S23;
+ static S S24;
+ static S S25;
+ static S S26;
+ static S S27;
+ static S S28;
+ static S S29;
+ static S S30;
+ static S S31;
+ static S S32;
+ static S S33;
+ static S S34;
+ static S S35;
+}
+// CHECK-LABEL: define dso_local void @"?MultipleStatics@@YAXXZ"()
+// CHECK: load i32, i32* @"?$S1@?1??MultipleStatics@@YAXXZ@4IA"
+// CHECK: and i32 {{.*}}, 1
+// CHECK: and i32 {{.*}}, 2
+// CHECK: and i32 {{.*}}, 4
+// CHECK: and i32 {{.*}}, 8
+// CHECK: and i32 {{.*}}, 16
+// ...
+// CHECK: and i32 {{.*}}, -2147483648
+// CHECK: load i32, i32* @"?$S1@?1??MultipleStatics@@[email protected]"
+// CHECK: and i32 {{.*}}, 1
+// CHECK: and i32 {{.*}}, 2
+// CHECK: and i32 {{.*}}, 4
+// CHECK: ret
+
+// Force WeakODRLinkage by using templates
+class A {
+ public:
+ A() {}
+ ~A() {}
+ int a;
+};
+
+template<typename T>
+class B {
+ public:
+ static A foo;
+};
+
+template<typename T> A B<T>::foo;
+
+inline S &UnreachableStatic() {
+ if (0) {
+ static S s; // bit 1
+ return s;
+ }
+ static S s; // bit 2
+ return s;
+}
+
+// CHECK-LABEL: define linkonce_odr dso_local dereferenceable({{[0-9]+}}) %struct.S* @"?UnreachableStatic@@YAAAUS@@XZ"() {{.*}} comdat
+// CHECK: and i32 {{.*}}, 2
+// CHECK: or i32 {{.*}}, 2
+// CHECK: ret
+
+inline S &getS() {
+ static S TheS;
+ return TheS;
+}
+
+// CHECK-LABEL: define linkonce_odr dso_local dereferenceable({{[0-9]+}}) %struct.S* @"?getS@@YAAAUS@@XZ"() {{.*}} comdat
+// CHECK: load i32, i32* @"??_B?1??getS@@YAAAUS@@XZ@51"
+// CHECK: and i32 {{.*}}, 1
+// CHECK: icmp eq i32 {{.*}}, 0
+// CHECK: br i1
+// init:
+// CHECK: or i32 {{.*}}, 1
+// CHECK: store i32 {{.*}}, i32* @"??_B?1??getS@@YAAAUS@@XZ@51"
+// CHECK: call x86_thiscallcc %struct.S* @"??0S@@QAE@XZ"(%struct.S* @"?TheS@?1??getS@@YAAAUS@@XZ@4U2@A")
+// CHECK: call i32 @atexit(void ()* @"??__FTheS@?1??getS@@YAAAUS@@XZ@YAXXZ")
+// CHECK: br label
+// init.end:
+// CHECK: ret %struct.S* @"?TheS@?1??getS@@YAAAUS@@XZ@4U2@A"
+
+inline int enum_in_function() {
+ // CHECK-LABEL: define linkonce_odr dso_local i32 @"?enum_in_function@@YAHXZ"() {{.*}} comdat
+ static enum e { foo, bar, baz } x;
+ // CHECK: @"?x@?1??enum_in_function@@YAHXZ@4W4e@?1??1@YAHXZ@A"
+ static int y;
+ // CHECK: @"?y@?1??enum_in_function@@YAHXZ@4HA"
+ return x + y;
+};
+
+struct T {
+ enum e { foo, bar, baz };
+ int enum_in_struct() {
+ // CHECK-LABEL: define linkonce_odr dso_local x86_thiscallcc i32 @"?enum_in_struct@T@@QAEHXZ"({{.*}}) {{.*}} comdat
+ static int x;
+ // CHECK: @"?x@?1??enum_in_struct@T@@QAEHXZ@4HA"
+ return x++;
+ }
+};
+
+inline int switch_test(int x) {
+ // CHECK-LABEL: define linkonce_odr dso_local i32 @"?switch_test@@YAHH@Z"(i32 %x) {{.*}} comdat
+ switch (x) {
+ static int a;
+ // CHECK: @"?a@?3??switch_test@@YAHH@Z@4HA"
+ case 0:
+ a++;
+ return 1;
+ case 1:
+ static int b;
+ // CHECK: @"?b@?3??switch_test@@YAHH@Z@4HA"
+ return b++;
+ case 2: {
+ static int c;
+ // CHECK: @"?c@?4??switch_test@@YAHH@Z@4HA"
+ return b + c++;
+ }
+ };
+}
+
+int f();
+inline void switch_test2() {
+ // CHECK-LABEL: define linkonce_odr dso_local void @"?switch_test2@@YAXXZ"() {{.*}} comdat
+ // CHECK: @"?x@?2??switch_test2@@YAXXZ@4HA"
+ switch (1) default: static int x = f();
+}
+
+namespace DynamicDLLImportInitVSMangling {
+ // Failing to pop the ExprEvalContexts when instantiating a dllimport var with
+ // dynamic initializer would cause subsequent static local numberings to be
+ // incorrect.
+ struct NonPOD { NonPOD(); };
+ template <typename T> struct A { static NonPOD x; };
+ template <typename T> NonPOD A<T>::x;
+ template struct __declspec(dllimport) A<int>;
+
+ inline int switch_test3() {
+ // CHECK-LABEL: define linkonce_odr dso_local i32 @"?switch_test3@DynamicDLLImportInitVSMangling@@YAHXZ"() {{.*}} comdat
+ static int local;
+ // CHECK: @"?local@?1??switch_test3@DynamicDLLImportInitVSMangling@@YAHXZ@4HA"
+ return local++;
+ }
+}
+
+void force_usage() {
+ UnreachableStatic();
+ getS();
+ (void)B<int>::foo; // (void) - force usage
+ enum_in_function();
+ (void)&T::enum_in_struct;
+ switch_test(1);
+ switch_test2();
+ DynamicDLLImportInitVSMangling::switch_test3();
+}
+
+// CHECK: define linkonce_odr dso_local void @"??__E?foo@?$B@H@@2VA@@A@@YAXXZ"() {{.*}} comdat
+// CHECK-NOT: and
+// CHECK-NOT: ?_Bfoo@
+// CHECK: call x86_thiscallcc %class.A* @"??0A@@QAE@XZ"
+// CHECK: call i32 @atexit(void ()* @"??__F?foo@?$B@H@@2VA@@A@@YAXXZ")
+// CHECK: ret void
+
+// CHECK: define linkonce_odr dso_local x86_thiscallcc %class.A* @"??0A@@QAE@XZ"({{.*}}) {{.*}} comdat
+
+// CHECK: define linkonce_odr dso_local x86_thiscallcc void @"??1A@@QAE@XZ"({{.*}}) {{.*}} comdat
+
+// CHECK: define internal void @"??__F?foo@?$B@H@@2VA@@A@@YAXXZ"
+// CHECK: call x86_thiscallcc void @"??1A@@QAE@XZ"{{.*}}foo
+// CHECK: ret void
+
+// CHECK: define internal void @_GLOBAL__sub_I_microsoft_abi_static_initializers.cpp()
+// CHECK: call void @"??__Es@@YAXXZ"()
+// CHECK: ret void
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-structors-alias.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-structors-alias.cpp
new file mode 100644
index 0000000..38f7b4c
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-structors-alias.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 -fno-rtti -mconstructor-aliases -O1 -disable-llvm-passes | FileCheck %s
+
+namespace test1 {
+template <typename T> class A {
+ ~A() {}
+};
+template class A<char>;
+// CHECK-DAG: define weak_odr dso_local x86_thiscallcc void @"??1?$A@D@test1@@AAE@XZ"
+}
+
+namespace test2 {
+struct A {
+ virtual ~A();
+};
+struct B : A {
+ B();
+ virtual ~B();
+};
+
+A::~A() {}
+B::~B() {}
+void foo() {
+ B b;
+}
+// CHECK-DAG: @"??1B@test2@@UAE@XZ" = dso_local unnamed_addr alias void (%"struct.test2::B"*), bitcast (void (%"struct.test2::A"*)* @"??1A@test2@@UAE@XZ" to void (%"struct.test2::B"*)*)
+}
+
+namespace test3 {
+struct A { virtual ~A(); };
+A::~A() {}
+}
+// CHECK-DAG: define dso_local x86_thiscallcc void @"??1A@test3@@UAE@XZ"(
+namespace test3 {
+template <typename T>
+struct B : A {
+ virtual ~B() { }
+};
+template struct B<int>;
+}
+// This has to be weak, and emitting weak aliases is fragile, so we don't do the
+// aliasing.
+// CHECK-DAG: define weak_odr dso_local x86_thiscallcc void @"??1?$B@H@test3@@UAE@XZ"(
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-structors-delayed-template.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-structors-delayed-template.cpp
new file mode 100644
index 0000000..6c4f370
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-structors-delayed-template.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -emit-llvm -fdelayed-template-parsing -std=c++11 -o - -triple=i386-pc-win32 %s > %t
+// RUN: FileCheck %s < %t
+
+// PR20671
+namespace vtable_referenced_from_template {
+struct ImplicitCtor {
+ virtual ~ImplicitCtor();
+};
+template <class T> void foo(T t) { new ImplicitCtor; }
+void bar() { foo(0); }
+// CHECK: store {{.*}} @"??_7ImplicitCtor@vtable_referenced_from_template@@6B@"
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-structors.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-structors.cpp
new file mode 100644
index 0000000..b0d2b56
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-structors.cpp
@@ -0,0 +1,487 @@
+// RUN: %clang_cc1 -emit-llvm -fno-rtti %s -std=c++11 -o - -mconstructor-aliases -triple=i386-pc-win32 -fno-rtti > %t
+// RUN: FileCheck %s < %t
+// vftables are emitted very late, so do another pass to try to keep the checks
+// in source order.
+// RUN: FileCheck --check-prefix DTORS %s < %t
+// RUN: FileCheck --check-prefix DTORS2 %s < %t
+// RUN: FileCheck --check-prefix DTORS3 %s < %t
+// RUN: FileCheck --check-prefix DTORS4 %s < %t
+//
+// RUN: %clang_cc1 -emit-llvm %s -o - -mconstructor-aliases -triple=x86_64-pc-win32 -fno-rtti -std=c++11 | FileCheck --check-prefix DTORS-X64 %s
+
+namespace basic {
+
+class A {
+ public:
+ A() { }
+ ~A();
+};
+
+void no_constructor_destructor_infinite_recursion() {
+ A a;
+
+// CHECK: define linkonce_odr dso_local x86_thiscallcc %"class.basic::A"* @"??0A@basic@@QAE@XZ"(%"class.basic::A"* returned %this) {{.*}} comdat {{.*}} {
+// CHECK: [[THIS_ADDR:%[.0-9A-Z_a-z]+]] = alloca %"class.basic::A"*, align 4
+// CHECK-NEXT: store %"class.basic::A"* %this, %"class.basic::A"** [[THIS_ADDR]], align 4
+// CHECK-NEXT: [[T1:%[.0-9A-Z_a-z]+]] = load %"class.basic::A"*, %"class.basic::A"** [[THIS_ADDR]]
+// CHECK-NEXT: ret %"class.basic::A"* [[T1]]
+// CHECK-NEXT: }
+}
+
+A::~A() {
+// Make sure that the destructor doesn't call itself:
+// CHECK: define {{.*}} @"??1A@basic@@QAE@XZ"
+// CHECK-NOT: call void @"??1A@basic@@QAE@XZ"
+// CHECK: ret
+}
+
+struct B {
+ B();
+};
+
+// Tests that we can define constructors outside the class (PR12784).
+B::B() {
+ // CHECK: define dso_local x86_thiscallcc %"struct.basic::B"* @"??0B@basic@@QAE@XZ"(%"struct.basic::B"* returned %this)
+ // CHECK: ret
+}
+
+struct C {
+ virtual ~C() {
+// DTORS: define linkonce_odr dso_local x86_thiscallcc i8* @"??_GC@basic@@UAEPAXI@Z"(%"struct.basic::C"* %this, i32 %should_call_delete) {{.*}} comdat {{.*}} {
+// DTORS: store i32 %should_call_delete, i32* %[[SHOULD_DELETE_VAR:[0-9a-z._]+]], align 4
+// DTORS: store i8* %{{.*}}, i8** %[[RETVAL:[0-9a-z._]+]]
+// DTORS: %[[SHOULD_DELETE_VALUE:[0-9a-z._]+]] = load i32, i32* %[[SHOULD_DELETE_VAR]]
+// DTORS: call x86_thiscallcc void @"??1C@basic@@UAE@XZ"(%"struct.basic::C"* %[[THIS:[0-9a-z]+]])
+// DTORS-NEXT: %[[CONDITION:[0-9]+]] = icmp eq i32 %[[SHOULD_DELETE_VALUE]], 0
+// DTORS-NEXT: br i1 %[[CONDITION]], label %[[CONTINUE_LABEL:[0-9a-z._]+]], label %[[CALL_DELETE_LABEL:[0-9a-z._]+]]
+//
+// DTORS: [[CALL_DELETE_LABEL]]
+// DTORS-NEXT: %[[THIS_AS_VOID:[0-9a-z]+]] = bitcast %"struct.basic::C"* %[[THIS]] to i8*
+// DTORS-NEXT: call void @"??3@YAXPAX@Z"(i8* %[[THIS_AS_VOID]])
+// DTORS-NEXT: br label %[[CONTINUE_LABEL]]
+//
+// DTORS: [[CONTINUE_LABEL]]
+// DTORS-NEXT: %[[RET:.*]] = load i8*, i8** %[[RETVAL]]
+// DTORS-NEXT: ret i8* %[[RET]]
+
+// Check that we do the mangling correctly on x64.
+// DTORS-X64: @"??_GC@basic@@UEAAPEAXI@Z"
+ }
+ virtual void foo();
+};
+
+// Emits the vftable in the output.
+void C::foo() {}
+
+void check_vftable_offset() {
+ C c;
+// The vftable pointer should point at the beginning of the vftable.
+// CHECK: [[THIS_PTR:%[0-9]+]] = bitcast %"struct.basic::C"* {{.*}} to i32 (...)***
+// CHECK: store i32 (...)** bitcast ({ [2 x i8*] }* @"??_7C@basic@@6B@" to i32 (...)**), i32 (...)*** [[THIS_PTR]]
+}
+
+void call_complete_dtor(C *obj_ptr) {
+// CHECK: define dso_local void @"?call_complete_dtor@basic@@YAXPAUC@1@@Z"(%"struct.basic::C"* %obj_ptr)
+ obj_ptr->~C();
+// CHECK: %[[OBJ_PTR_VALUE:.*]] = load %"struct.basic::C"*, %"struct.basic::C"** %{{.*}}, align 4
+// CHECK-NEXT: %[[PVTABLE:.*]] = bitcast %"struct.basic::C"* %[[OBJ_PTR_VALUE]] to i8* (%"struct.basic::C"*, i32)***
+// CHECK-NEXT: %[[VTABLE:.*]] = load i8* (%"struct.basic::C"*, i32)**, i8* (%"struct.basic::C"*, i32)*** %[[PVTABLE]]
+// CHECK-NEXT: %[[PVDTOR:.*]] = getelementptr inbounds i8* (%"struct.basic::C"*, i32)*, i8* (%"struct.basic::C"*, i32)** %[[VTABLE]], i64 0
+// CHECK-NEXT: %[[VDTOR:.*]] = load i8* (%"struct.basic::C"*, i32)*, i8* (%"struct.basic::C"*, i32)** %[[PVDTOR]]
+// CHECK-NEXT: call x86_thiscallcc i8* %[[VDTOR]](%"struct.basic::C"* %[[OBJ_PTR_VALUE]], i32 0)
+// CHECK-NEXT: ret void
+}
+
+void call_deleting_dtor(C *obj_ptr) {
+// CHECK: define dso_local void @"?call_deleting_dtor@basic@@YAXPAUC@1@@Z"(%"struct.basic::C"* %obj_ptr)
+ delete obj_ptr;
+// CHECK: %[[OBJ_PTR_VALUE:.*]] = load %"struct.basic::C"*, %"struct.basic::C"** %{{.*}}, align 4
+// CHECK: br i1 {{.*}}, label %[[DELETE_NULL:.*]], label %[[DELETE_NOTNULL:.*]]
+
+// CHECK: [[DELETE_NOTNULL]]
+// CHECK-NEXT: %[[PVTABLE:.*]] = bitcast %"struct.basic::C"* %[[OBJ_PTR_VALUE]] to i8* (%"struct.basic::C"*, i32)***
+// CHECK-NEXT: %[[VTABLE:.*]] = load i8* (%"struct.basic::C"*, i32)**, i8* (%"struct.basic::C"*, i32)*** %[[PVTABLE]]
+// CHECK-NEXT: %[[PVDTOR:.*]] = getelementptr inbounds i8* (%"struct.basic::C"*, i32)*, i8* (%"struct.basic::C"*, i32)** %[[VTABLE]], i64 0
+// CHECK-NEXT: %[[VDTOR:.*]] = load i8* (%"struct.basic::C"*, i32)*, i8* (%"struct.basic::C"*, i32)** %[[PVDTOR]]
+// CHECK-NEXT: call x86_thiscallcc i8* %[[VDTOR]](%"struct.basic::C"* %[[OBJ_PTR_VALUE]], i32 1)
+// CHECK: ret void
+}
+
+void call_deleting_dtor_and_global_delete(C *obj_ptr) {
+// CHECK: define dso_local void @"?call_deleting_dtor_and_global_delete@basic@@YAXPAUC@1@@Z"(%"struct.basic::C"* %obj_ptr)
+ ::delete obj_ptr;
+// CHECK: %[[OBJ_PTR_VALUE:.*]] = load %"struct.basic::C"*, %"struct.basic::C"** %{{.*}}, align 4
+// CHECK: br i1 {{.*}}, label %[[DELETE_NULL:.*]], label %[[DELETE_NOTNULL:.*]]
+
+// CHECK: [[DELETE_NOTNULL]]
+// CHECK-NEXT: %[[PVTABLE:.*]] = bitcast %"struct.basic::C"* %[[OBJ_PTR_VALUE]] to i8* (%"struct.basic::C"*, i32)***
+// CHECK-NEXT: %[[VTABLE:.*]] = load i8* (%"struct.basic::C"*, i32)**, i8* (%"struct.basic::C"*, i32)*** %[[PVTABLE]]
+// CHECK-NEXT: %[[PVDTOR:.*]] = getelementptr inbounds i8* (%"struct.basic::C"*, i32)*, i8* (%"struct.basic::C"*, i32)** %[[VTABLE]], i64 0
+// CHECK-NEXT: %[[VDTOR:.*]] = load i8* (%"struct.basic::C"*, i32)*, i8* (%"struct.basic::C"*, i32)** %[[PVDTOR]]
+// CHECK-NEXT: %[[CALL:.*]] = call x86_thiscallcc i8* %[[VDTOR]](%"struct.basic::C"* %[[OBJ_PTR_VALUE]], i32 0)
+// CHECK-NEXT: call void @"??3@YAXPAX@Z"(i8* %[[CALL]])
+// CHECK: ret void
+}
+
+struct D {
+ static int foo();
+
+ D() {
+ static int ctor_static = foo();
+ // CHECK that the static in the ctor gets mangled correctly:
+ // CHECK: @"?ctor_static@?1???0D@basic@@QAE@XZ@4HA"
+ }
+ ~D() {
+ static int dtor_static = foo();
+ // CHECK that the static in the dtor gets mangled correctly:
+ // CHECK: @"?dtor_static@?1???1D@basic@@QAE@XZ@4HA"
+ }
+};
+
+void use_D() { D c; }
+
+} // end namespace basic
+
+namespace dtor_in_second_nvbase {
+
+struct A {
+ virtual void f(); // A needs vftable to be primary.
+};
+struct B {
+ virtual ~B();
+};
+struct C : A, B {
+ virtual ~C();
+};
+
+C::~C() {
+// CHECK-LABEL: define dso_local x86_thiscallcc void @"??1C@dtor_in_second_nvbase@@UAE@XZ"
+// CHECK: (%"struct.dtor_in_second_nvbase::C"* %this)
+// No this adjustment!
+// CHECK-NOT: getelementptr
+// CHECK: load %"struct.dtor_in_second_nvbase::C"*, %"struct.dtor_in_second_nvbase::C"** %{{.*}}
+// Now we this-adjust before calling ~B.
+// CHECK: bitcast %"struct.dtor_in_second_nvbase::C"* %{{.*}} to i8*
+// CHECK: getelementptr inbounds i8, i8* %{{.*}}, i32 4
+// CHECK: bitcast i8* %{{.*}} to %"struct.dtor_in_second_nvbase::B"*
+// CHECK: call x86_thiscallcc void @"??1B@dtor_in_second_nvbase@@UAE@XZ"
+// CHECK: (%"struct.dtor_in_second_nvbase::B"* %{{.*}})
+// CHECK: ret void
+}
+
+void foo() {
+ C c;
+}
+// DTORS2-LABEL: define linkonce_odr dso_local x86_thiscallcc i8* @"??_EC@dtor_in_second_nvbase@@W3AEPAXI@Z"
+// DTORS2: (%"struct.dtor_in_second_nvbase::C"* %this, i32 %should_call_delete)
+// Do an adjustment from B* to C*.
+// DTORS2: getelementptr i8, i8* %{{.*}}, i32 -4
+// DTORS2: bitcast i8* %{{.*}} to %"struct.dtor_in_second_nvbase::C"*
+// DTORS2: %[[CALL:.*]] = tail call x86_thiscallcc i8* @"??_GC@dtor_in_second_nvbase@@UAEPAXI@Z"
+// DTORS2: ret i8* %[[CALL]]
+
+}
+
+namespace test2 {
+// Just like dtor_in_second_nvbase, except put that in a vbase of a diamond.
+
+// C's dtor is in the non-primary base.
+struct A { virtual void f(); };
+struct B { virtual ~B(); };
+struct C : A, B { virtual ~C(); int c; };
+
+// Diamond hierarchy, with C as the shared vbase.
+struct D : virtual C { int d; };
+struct E : virtual C { int e; };
+struct F : D, E { ~F(); int f; };
+
+F::~F() {
+// CHECK-LABEL: define dso_local x86_thiscallcc void @"??1F@test2@@UAE@XZ"(%"struct.test2::F"*{{[^,]*}})
+// Do an adjustment from C vbase subobject to F as though F was the
+// complete type.
+// CHECK: getelementptr inbounds i8, i8* %{{.*}}, i32 -20
+// CHECK: bitcast i8* %{{.*}} to %"struct.test2::F"*
+// CHECK: store %"struct.test2::F"*
+}
+
+void foo() {
+ F f;
+}
+// DTORS3-LABEL: define linkonce_odr dso_local x86_thiscallcc void @"??_DF@test2@@QAEXXZ"({{.*}} {{.*}} comdat
+// Do an adjustment from C* to F*.
+// DTORS3: getelementptr i8, i8* %{{.*}}, i32 20
+// DTORS3: bitcast i8* %{{.*}} to %"struct.test2::F"*
+// DTORS3: call x86_thiscallcc void @"??1F@test2@@UAE@XZ"
+// DTORS3: ret void
+
+}
+
+namespace constructors {
+
+struct A {
+ A() {}
+};
+
+struct B : A {
+ B();
+ ~B();
+};
+
+B::B() {
+ // CHECK: define dso_local x86_thiscallcc %"struct.constructors::B"* @"??0B@constructors@@QAE@XZ"(%"struct.constructors::B"* returned %this)
+ // CHECK: call x86_thiscallcc %"struct.constructors::A"* @"??0A@constructors@@QAE@XZ"(%"struct.constructors::A"* %{{.*}})
+ // CHECK: ret
+}
+
+struct C : virtual A {
+ C();
+};
+
+C::C() {
+ // CHECK: define dso_local x86_thiscallcc %"struct.constructors::C"* @"??0C@constructors@@QAE@XZ"(%"struct.constructors::C"* returned %this, i32 %is_most_derived)
+ // TODO: make sure this works in the Release build too;
+ // CHECK: store i32 %is_most_derived, i32* %[[IS_MOST_DERIVED_VAR:.*]], align 4
+ // CHECK: %[[IS_MOST_DERIVED_VAL:.*]] = load i32, i32* %[[IS_MOST_DERIVED_VAR]]
+ // CHECK: %[[SHOULD_CALL_VBASE_CTORS:.*]] = icmp ne i32 %[[IS_MOST_DERIVED_VAL]], 0
+ // CHECK: br i1 %[[SHOULD_CALL_VBASE_CTORS]], label %[[INIT_VBASES:.*]], label %[[SKIP_VBASES:.*]]
+ //
+ // CHECK: [[INIT_VBASES]]
+ // CHECK-NEXT: %[[this_i8:.*]] = bitcast %"struct.constructors::C"* %{{.*}} to i8*
+ // CHECK-NEXT: %[[vbptr_off:.*]] = getelementptr inbounds i8, i8* %[[this_i8]], i32 0
+ // CHECK-NEXT: %[[vbptr:.*]] = bitcast i8* %[[vbptr_off]] to i32**
+ // CHECK-NEXT: store i32* getelementptr inbounds ([2 x i32], [2 x i32]* @"??_8C@constructors@@7B@", i32 0, i32 0), i32** %[[vbptr]]
+ // CHECK-NEXT: bitcast %"struct.constructors::C"* %{{.*}} to i8*
+ // CHECK-NEXT: getelementptr inbounds i8, i8* %{{.*}}, i32 4
+ // CHECK-NEXT: bitcast i8* %{{.*}} to %"struct.constructors::A"*
+ // CHECK-NEXT: call x86_thiscallcc %"struct.constructors::A"* @"??0A@constructors@@QAE@XZ"(%"struct.constructors::A"* %{{.*}})
+ // CHECK-NEXT: br label %[[SKIP_VBASES]]
+ //
+ // CHECK: [[SKIP_VBASES]]
+ // Class C does not define or override methods, so shouldn't change the vfptr.
+ // CHECK-NOT: @"??_7C@constructors@@6B@"
+ // CHECK: ret
+}
+
+void create_C() {
+ C c;
+ // CHECK: define dso_local void @"?create_C@constructors@@YAXXZ"()
+ // CHECK: call x86_thiscallcc %"struct.constructors::C"* @"??0C@constructors@@QAE@XZ"(%"struct.constructors::C"* %c, i32 1)
+ // CHECK: ret
+}
+
+struct D : C {
+ D();
+};
+
+D::D() {
+ // CHECK: define dso_local x86_thiscallcc %"struct.constructors::D"* @"??0D@constructors@@QAE@XZ"(%"struct.constructors::D"* returned %this, i32 %is_most_derived) unnamed_addr
+ // CHECK: store i32 %is_most_derived, i32* %[[IS_MOST_DERIVED_VAR:.*]], align 4
+ // CHECK: %[[IS_MOST_DERIVED_VAL:.*]] = load i32, i32* %[[IS_MOST_DERIVED_VAR]]
+ // CHECK: %[[SHOULD_CALL_VBASE_CTORS:.*]] = icmp ne i32 %[[IS_MOST_DERIVED_VAL]], 0
+ // CHECK: br i1 %[[SHOULD_CALL_VBASE_CTORS]], label %[[INIT_VBASES:.*]], label %[[SKIP_VBASES:.*]]
+ //
+ // CHECK: [[INIT_VBASES]]
+ // CHECK-NEXT: %[[this_i8:.*]] = bitcast %"struct.constructors::D"* %{{.*}} to i8*
+ // CHECK-NEXT: %[[vbptr_off:.*]] = getelementptr inbounds i8, i8* %[[this_i8]], i32 0
+ // CHECK-NEXT: %[[vbptr:.*]] = bitcast i8* %[[vbptr_off]] to i32**
+ // CHECK-NEXT: store i32* getelementptr inbounds ([2 x i32], [2 x i32]* @"??_8D@constructors@@7B@", i32 0, i32 0), i32** %[[vbptr]]
+ // CHECK-NEXT: bitcast %"struct.constructors::D"* %{{.*}} to i8*
+ // CHECK-NEXT: getelementptr inbounds i8, i8* %{{.*}}, i32 4
+ // CHECK-NEXT: bitcast i8* %{{.*}} to %"struct.constructors::A"*
+ // CHECK-NEXT: call x86_thiscallcc %"struct.constructors::A"* @"??0A@constructors@@QAE@XZ"(%"struct.constructors::A"* %{{.*}})
+ // CHECK-NEXT: br label %[[SKIP_VBASES]]
+ //
+ // CHECK: [[SKIP_VBASES]]
+ // CHECK: call x86_thiscallcc %"struct.constructors::C"* @"??0C@constructors@@QAE@XZ"(%"struct.constructors::C"* %{{.*}}, i32 0)
+ // CHECK: ret
+}
+
+struct E : virtual C {
+ E();
+};
+
+E::E() {
+ // CHECK: define dso_local x86_thiscallcc %"struct.constructors::E"* @"??0E@constructors@@QAE@XZ"(%"struct.constructors::E"* returned %this, i32 %is_most_derived) unnamed_addr
+ // CHECK: store i32 %is_most_derived, i32* %[[IS_MOST_DERIVED_VAR:.*]], align 4
+ // CHECK: %[[IS_MOST_DERIVED_VAL:.*]] = load i32, i32* %[[IS_MOST_DERIVED_VAR]]
+ // CHECK: %[[SHOULD_CALL_VBASE_CTORS:.*]] = icmp ne i32 %[[IS_MOST_DERIVED_VAL]], 0
+ // CHECK: br i1 %[[SHOULD_CALL_VBASE_CTORS]], label %[[INIT_VBASES:.*]], label %[[SKIP_VBASES:.*]]
+ //
+ // CHECK: [[INIT_VBASES]]
+ // CHECK-NEXT: %[[this_i8:.*]] = bitcast %"struct.constructors::E"* %{{.*}} to i8*
+ // CHECK-NEXT: %[[offs:.*]] = getelementptr inbounds i8, i8* %[[this_i8]], i32 0
+ // CHECK-NEXT: %[[vbptr_E:.*]] = bitcast i8* %[[offs]] to i32**
+ // CHECK-NEXT: store i32* getelementptr inbounds ([3 x i32], [3 x i32]* @"??_8E@constructors@@7B01@@", i32 0, i32 0), i32** %[[vbptr_E]]
+ // CHECK-NEXT: %[[offs:.*]] = getelementptr inbounds i8, i8* %[[this_i8]], i32 4
+ // CHECK-NEXT: %[[vbptr_C:.*]] = bitcast i8* %[[offs]] to i32**
+ // CHECK-NEXT: store i32* getelementptr inbounds ([2 x i32], [2 x i32]* @"??_8E@constructors@@7BC@1@@", i32 0, i32 0), i32** %[[vbptr_C]]
+ // CHECK-NEXT: bitcast %"struct.constructors::E"* %{{.*}} to i8*
+ // CHECK-NEXT: getelementptr inbounds i8, i8* %{{.*}}, i32 4
+ // CHECK-NEXT: bitcast i8* %{{.*}} to %"struct.constructors::A"*
+ // CHECK-NEXT: call x86_thiscallcc %"struct.constructors::A"* @"??0A@constructors@@QAE@XZ"(%"struct.constructors::A"* %{{.*}})
+ // CHECK: call x86_thiscallcc %"struct.constructors::C"* @"??0C@constructors@@QAE@XZ"(%"struct.constructors::C"* %{{.*}}, i32 0)
+ // CHECK-NEXT: br label %[[SKIP_VBASES]]
+ //
+ // CHECK: [[SKIP_VBASES]]
+ // CHECK: ret
+}
+
+// PR16735 - even abstract classes should have a constructor emitted.
+struct F {
+ F();
+ virtual void f() = 0;
+};
+
+F::F() {}
+// CHECK: define dso_local x86_thiscallcc %"struct.constructors::F"* @"??0F@constructors@@QAE@XZ"
+
+} // end namespace constructors
+
+namespace dtors {
+
+struct A {
+ ~A();
+};
+
+void call_nv_complete(A *a) {
+ a->~A();
+// CHECK: define dso_local void @"?call_nv_complete@dtors@@YAXPAUA@1@@Z"
+// CHECK: call x86_thiscallcc void @"??1A@dtors@@QAE@XZ"
+// CHECK: ret
+}
+
+// CHECK: declare dso_local x86_thiscallcc void @"??1A@dtors@@QAE@XZ"
+
+// Now try some virtual bases, where we need the complete dtor.
+
+struct B : virtual A { ~B(); };
+struct C : virtual A { ~C(); };
+struct D : B, C { ~D(); };
+
+void call_vbase_complete(D *d) {
+ d->~D();
+// CHECK: define dso_local void @"?call_vbase_complete@dtors@@YAXPAUD@1@@Z"
+// CHECK: call x86_thiscallcc void @"??_DD@dtors@@QAEXXZ"(%"struct.dtors::D"* %{{[^,]+}})
+// CHECK: ret
+}
+
+// The complete dtor should call the base dtors for D and the vbase A (once).
+// CHECK: define linkonce_odr dso_local x86_thiscallcc void @"??_DD@dtors@@QAEXXZ"({{.*}}) {{.*}} comdat
+// CHECK-NOT: call
+// CHECK: call x86_thiscallcc void @"??1D@dtors@@QAE@XZ"
+// CHECK-NOT: call
+// CHECK: call x86_thiscallcc void @"??1A@dtors@@QAE@XZ"
+// CHECK-NOT: call
+// CHECK: ret
+
+void destroy_d_complete() {
+ D d;
+// CHECK: define dso_local void @"?destroy_d_complete@dtors@@YAXXZ"
+// CHECK: call x86_thiscallcc void @"??_DD@dtors@@QAEXXZ"(%"struct.dtors::D"* %{{[^,]+}})
+// CHECK: ret
+}
+
+// FIXME: Clang manually inlines the deletion, so we don't get a call to the
+// deleting dtor (_G). The only way to call deleting dtors currently is through
+// a vftable.
+void call_nv_deleting_dtor(D *d) {
+ delete d;
+// CHECK: define dso_local void @"?call_nv_deleting_dtor@dtors@@YAXPAUD@1@@Z"
+// CHECK: call x86_thiscallcc void @"??_DD@dtors@@QAEXXZ"(%"struct.dtors::D"* %{{[^,]+}})
+// CHECK: call void @"??3@YAXPAX@Z"
+// CHECK: ret
+}
+
+}
+
+namespace test1 {
+struct A { };
+struct B : virtual A {
+ B(int *a);
+ B(const char *a, ...);
+ __cdecl B(short *a);
+};
+B::B(int *a) {}
+B::B(const char *a, ...) {}
+B::B(short *a) {}
+// CHECK: define dso_local x86_thiscallcc %"struct.test1::B"* @"??0B@test1@@QAE@PAH@Z"
+// CHECK: (%"struct.test1::B"* returned %this, i32* %a, i32 %is_most_derived)
+// CHECK: define dso_local %"struct.test1::B"* @"??0B@test1@@QAA@PBDZZ"
+// CHECK: (%"struct.test1::B"* returned %this, i32 %is_most_derived, i8* %a, ...)
+// CHECK: define dso_local x86_thiscallcc %"struct.test1::B"* @"??0B@test1@@QAE@PAF@Z"
+// CHECK: (%"struct.test1::B"* returned %this, i16* %a, i32 %is_most_derived)
+
+void construct_b() {
+ int a;
+ B b1(&a);
+ B b2("%d %d", 1, 2);
+}
+// CHECK-LABEL: define dso_local void @"?construct_b@test1@@YAXXZ"()
+// CHECK: call x86_thiscallcc %"struct.test1::B"* @"??0B@test1@@QAE@PAH@Z"
+// CHECK: (%"struct.test1::B"* {{.*}}, i32* {{.*}}, i32 1)
+// CHECK: call %"struct.test1::B"* (%"struct.test1::B"*, i32, i8*, ...) @"??0B@test1@@QAA@PBDZZ"
+// CHECK: (%"struct.test1::B"* {{.*}}, i32 1, i8* {{.*}}, i32 1, i32 2)
+}
+
+namespace implicit_copy_vtable {
+// This was a crash that only reproduced in ABIs without key functions.
+struct ImplicitCopy {
+ // implicit copy ctor
+ virtual ~ImplicitCopy();
+};
+void CreateCopy(ImplicitCopy *a) {
+ new ImplicitCopy(*a);
+}
+// CHECK: store {{.*}} @"??_7ImplicitCopy@implicit_copy_vtable@@6B@"
+
+struct MoveOnly {
+ MoveOnly(MoveOnly &&o) = default;
+ virtual ~MoveOnly();
+};
+MoveOnly &&f();
+void g() { new MoveOnly(f()); }
+// CHECK: store {{.*}} @"??_7MoveOnly@implicit_copy_vtable@@6B@"
+}
+
+namespace delegating_ctor {
+struct Y {};
+struct X : virtual Y {
+ X(int);
+ X();
+};
+X::X(int) : X() {}
+}
+// CHECK: define dso_local x86_thiscallcc %"struct.delegating_ctor::X"* @"??0X@delegating_ctor@@QAE@H@Z"(
+// CHECK: %[[is_most_derived_addr:.*]] = alloca i32, align 4
+// CHECK: store i32 %is_most_derived, i32* %[[is_most_derived_addr]]
+// CHECK: %[[is_most_derived:.*]] = load i32, i32* %[[is_most_derived_addr]]
+// CHECK: call x86_thiscallcc {{.*}}* @"??0X@delegating_ctor@@QAE@XZ"({{.*}} i32 %[[is_most_derived]])
+
+// Dtor thunks for classes in anonymous namespaces should be internal, not
+// linkonce_odr.
+namespace {
+struct A {
+ virtual ~A() { }
+};
+}
+void *getA() {
+ return (void*)new A();
+}
+// CHECK: define internal x86_thiscallcc i8* @"??_GA@?A0x{{[^@]*}}@@UAEPAXI@Z"
+// CHECK: (%"struct.(anonymous namespace)::A"* %this, i32 %should_call_delete)
+// CHECK: define internal x86_thiscallcc void @"??1A@?A0x{{[^@]*}}@@UAE@XZ"
+// CHECK: (%"struct.(anonymous namespace)::A"* %this)
+
+// Check that we correctly transform __stdcall to __thiscall for ctors and
+// dtors.
+class G {
+ public:
+ __stdcall G() {};
+// DTORS4: define linkonce_odr dso_local x86_thiscallcc %class.G* @"??0G@@QAE@XZ"
+ __stdcall ~G() {};
+// DTORS4: define linkonce_odr dso_local x86_thiscallcc void @"??1G@@QAE@XZ"
+};
+
+extern void testG() {
+ G g;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-thread-safe-statics.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-thread-safe-statics.cpp
new file mode 100644
index 0000000..a5bb874
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-thread-safe-statics.cpp
@@ -0,0 +1,100 @@
+// RUN: %clang_cc1 -fexceptions -fcxx-exceptions -fms-extensions -fms-compatibility -fms-compatibility-version=19 -std=c++11 -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
+// REQUIRES: asserts
+
+struct S {
+ S();
+ ~S();
+};
+
+// CHECK-DAG: @"?s@?1??f@@YAAAUS@@XZ@4U2@A" = linkonce_odr dso_local thread_local global %struct.S zeroinitializer
+// CHECK-DAG: @"??__J?1??f@@YAAAUS@@XZ@51" = linkonce_odr thread_local global i32 0
+// CHECK-DAG: @"?s@?1??g@@YAAAUS@@XZ@4U2@A" = linkonce_odr dso_local global %struct.S zeroinitializer
+// CHECK-DAG: @"?$TSS0@?1??g@@YAAAUS@@XZ@4HA" = linkonce_odr global i32 0
+// CHECK-DAG: @_Init_thread_epoch = external thread_local global i32, align 4
+// CHECK-DAG: @"?j@?1??h@@YAAAUS@@_N@Z@4U2@A" = linkonce_odr dso_local thread_local global %struct.S zeroinitializer
+// CHECK-DAG: @"??__J?1??h@@YAAAUS@@_N@Z@51" = linkonce_odr thread_local global i32 0
+// CHECK-DAG: @"?i@?1??h@@YAAAUS@@_N@Z@4U2@A" = linkonce_odr dso_local global %struct.S zeroinitializer
+// CHECK-DAG: @"?$TSS0@?1??h@@YAAAUS@@_N@Z@4HA" = linkonce_odr global i32 0
+// CHECK-DAG: @"?i@?1??g1@@YAHXZ@4HA" = internal global i32 0, align 4
+// CHECK-DAG: @"?$TSS0@?1??g1@@YAHXZ@4HA" = internal global i32 0, align 4
+
+// CHECK-LABEL: define {{.*}} @"?f@@YAAAUS@@XZ"()
+// CHECK-SAME: personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
+extern inline S &f() {
+ static thread_local S s;
+// CHECK: %[[guard:.*]] = load i32, i32* @"??__J?1??f@@YAAAUS@@XZ@51"
+// CHECK-NEXT: %[[mask:.*]] = and i32 %[[guard]], 1
+// CHECK-NEXT: %[[cmp:.*]] = icmp eq i32 %[[mask]], 0
+// CHECK-NEXT: br i1 %[[cmp]], label %[[init:.*]], label %[[init_end:.*]], !prof ![[unlikely_threadlocal:.*]]
+//
+// CHECK: [[init]]:
+// CHECK-NEXT: %[[or:.*]] = or i32 %[[guard]], 1
+// CHECK-NEXT: store i32 %[[or]], i32* @"??__J?1??f@@YAAAUS@@XZ@51"
+// CHECK-NEXT: invoke {{.*}} @"??0S@@QAE@XZ"(%struct.S* @"?s@?1??f@@YAAAUS@@XZ@4U2@A")
+// CHECK-NEXT: to label %[[invoke_cont:.*]] unwind label %[[lpad:.*]]
+//
+// CHECK: [[invoke_cont]]:
+// CHECK-NEXT: call i32 @__tlregdtor(void ()* @"??__Fs@?1??f@@YAAAUS@@XZ@YAXXZ")
+// CHECK-NEXT: br label %[[init_end:.*]]
+
+// CHECK: [[init_end]]:
+// CHECK-NEXT: ret %struct.S* @"?s@?1??f@@YAAAUS@@XZ@4U2@A"
+
+// CHECK: [[lpad:.*]]:
+// CHECK-NEXT: cleanuppad within none []
+// CHECK: %[[guard:.*]] = load i32, i32* @"??__J?1??f@@YAAAUS@@XZ@51"
+// CHECK-NEXT: %[[mask:.*]] = and i32 %[[guard]], -2
+// CHECK-NEXT: store i32 %[[mask]], i32* @"??__J?1??f@@YAAAUS@@XZ@51"
+// CHECK-NEXT: cleanupret {{.*}} unwind to caller
+ return s;
+}
+
+
+// CHECK-LABEL: define {{.*}} @"?g@@YAAAUS@@XZ"()
+extern inline S &g() {
+ static S s;
+// CHECK: %[[guard:.*]] = load atomic i32, i32* @"?$TSS0@?1??g@@YAAAUS@@XZ@4HA" unordered, align 4
+// CHECK-NEXT: %[[epoch:.*]] = load i32, i32* @_Init_thread_epoch
+// CHECK-NEXT: %[[cmp:.*]] = icmp sgt i32 %[[guard]], %[[epoch]]
+// CHECK-NEXT: br i1 %[[cmp]], label %[[init_attempt:.*]], label %[[init_end:.*]], !prof ![[unlikely_staticlocal:.*]]
+//
+// CHECK: [[init_attempt]]:
+// CHECK-NEXT: call void @_Init_thread_header(i32* @"?$TSS0@?1??g@@YAAAUS@@XZ@4HA")
+// CHECK-NEXT: %[[guard2:.*]] = load atomic i32, i32* @"?$TSS0@?1??g@@YAAAUS@@XZ@4HA" unordered, align 4
+// CHECK-NEXT: %[[cmp2:.*]] = icmp eq i32 %[[guard2]], -1
+// CHECK-NEXT: br i1 %[[cmp2]], label %[[init:.*]], label %[[init_end:.*]]
+//
+// CHECK: [[init]]:
+// CHECK-NEXT: invoke {{.*}} @"??0S@@QAE@XZ"(%struct.S* @"?s@?1??g@@YAAAUS@@XZ@4U2@A")
+// CHECK-NEXT: to label %[[invoke_cont:.*]] unwind label %[[lpad:.*]]
+//
+// CHECK: [[invoke_cont]]:
+// CHECK-NEXT: call i32 @atexit(void ()* @"??__Fs@?1??g@@YAAAUS@@XZ@YAXXZ")
+// CHECK-NEXT: call void @_Init_thread_footer(i32* @"?$TSS0@?1??g@@YAAAUS@@XZ@4HA")
+// CHECK-NEXT: br label %init.end
+//
+// CHECK: [[init_end]]:
+// CHECK-NEXT: ret %struct.S* @"?s@?1??g@@YAAAUS@@XZ@4U2@A"
+//
+// CHECK: [[lpad]]:
+// CHECK-NEXT: cleanuppad within none []
+// CHECK: call void @_Init_thread_abort(i32* @"?$TSS0@?1??g@@YAAAUS@@XZ@4HA")
+// CHECK-NEXT: cleanupret {{.*}} unwind to caller
+ return s;
+}
+
+extern inline S&h(bool b) {
+ static thread_local S j;
+ static S i;
+ return b ? j : i;
+}
+
+// CHECK-LABEL: define dso_local i32 @"?g1@@YAHXZ"()
+int f1();
+int g1() {
+ static int i = f1();
+ return i;
+}
+
+// CHECK-DAG: ![[unlikely_threadlocal]] = !{!"branch_weights", i32 1, i32 1023}
+// CHECK-DAG: ![[unlikely_staticlocal]] = !{!"branch_weights", i32 1, i32 1048575}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-throw.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-throw.cpp
new file mode 100644
index 0000000..f55b94a
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-throw.cpp
@@ -0,0 +1,140 @@
+// RUN: %clang_cc1 -emit-llvm -o - -triple=i386-pc-win32 -std=c++11 %s -fcxx-exceptions -fms-extensions | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -o - -triple=i386-pc-win32 -std=c++11 %s -fcxx-exceptions -fms-extensions -DSTD | FileCheck %s
+
+// CHECK-DAG: @"??_R0?AUY@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"??_7type_info@@6B@", i8* null, [8 x i8] c".?AUY@@\00" }, comdat
+// CHECK-DAG: @"_CT??_R0?AUY@@@8??0Y@@QAE@ABU0@@Z8" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 4, i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUY@@@8" to i8*), i32 0, i32 -1, i32 0, i32 8, i8* bitcast (%struct.Y* (%struct.Y*, %struct.Y*, i32)* @"??0Y@@QAE@ABU0@@Z" to i8*) }, section ".xdata", comdat
+// CHECK-DAG: @"??_R0?AUZ@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"??_7type_info@@6B@", i8* null, [8 x i8] c".?AUZ@@\00" }, comdat
+// CHECK-DAG: @"_CT??_R0?AUZ@@@81" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUZ@@@8" to i8*), i32 0, i32 -1, i32 0, i32 1, i8* null }, section ".xdata", comdat
+// CHECK-DAG: @"??_R0?AUW@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"??_7type_info@@6B@", i8* null, [8 x i8] c".?AUW@@\00" }, comdat
+// CHECK-DAG: @"_CT??_R0?AUW@@@8??0W@@QAE@ABU0@@Z44" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 4, i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUW@@@8" to i8*), i32 4, i32 -1, i32 0, i32 4, i8* bitcast (%struct.W* (%struct.W*, %struct.W*, i32)* @"??0W@@QAE@ABU0@@Z" to i8*) }, section ".xdata", comdat
+// CHECK-DAG: @"??_R0?AUM@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"??_7type_info@@6B@", i8* null, [8 x i8] c".?AUM@@\00" }, comdat
+// CHECK-DAG: @"_CT??_R0?AUM@@@818" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUM@@@8" to i8*), i32 8, i32 -1, i32 0, i32 1, i8* null }, section ".xdata", comdat
+// CHECK-DAG: @"??_R0?AUV@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"??_7type_info@@6B@", i8* null, [8 x i8] c".?AUV@@\00" }, comdat
+// CHECK-DAG: @"_CT??_R0?AUV@@@81044" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUV@@@8" to i8*), i32 0, i32 4, i32 4, i32 1, i8* null }, section ".xdata", comdat
+// CHECK-DAG: @"_CTA5?AUY@@" = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.5 { i32 5, [5 x %eh.CatchableType*] [%eh.CatchableType* @"_CT??_R0?AUY@@@8??0Y@@QAE@ABU0@@Z8", %eh.CatchableType* @"_CT??_R0?AUZ@@@81", %eh.CatchableType* @"_CT??_R0?AUW@@@8??0W@@QAE@ABU0@@Z44", %eh.CatchableType* @"_CT??_R0?AUM@@@818", %eh.CatchableType* @"_CT??_R0?AUV@@@81044"] }, section ".xdata", comdat
+// CHECK-DAG: @"_TI5?AUY@@" = linkonce_odr unnamed_addr constant %eh.ThrowInfo { i32 0, i8* bitcast (void (%struct.Y*)* @"??_DY@@QAEXXZ" to i8*), i8* null, i8* bitcast (%eh.CatchableTypeArray.5* @"_CTA5?AUY@@" to i8*) }, section ".xdata", comdat
+// CHECK-DAG: @"_CT??_R0?AUDefault@@@8??_ODefault@@QAEXAAU0@@Z1" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor13* @"??_R0?AUDefault@@@8" to i8*), i32 0, i32 -1, i32 0, i32 1, i8* bitcast (void (%struct.Default*, %struct.Default*)* @"??_ODefault@@QAEXAAU0@@Z" to i8*) }, section ".xdata", comdat
+// CHECK-DAG: @"_CT??_R0?AUVariadic@@@8??_OVariadic@@QAEXAAU0@@Z1" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor14* @"??_R0?AUVariadic@@@8" to i8*), i32 0, i32 -1, i32 0, i32 1, i8* bitcast (void (%struct.Variadic*, %struct.Variadic*)* @"??_OVariadic@@QAEXAAU0@@Z" to i8*) }, section ".xdata", comdat
+// CHECK-DAG: @"_CT??_R0?AUTemplateWithDefault@@@8??$?_OH@TemplateWithDefault@@QAEXAAU0@@Z1" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor25* @"??_R0?AUTemplateWithDefault@@@8" to i8*), i32 0, i32 -1, i32 0, i32 1, i8* bitcast (void (%struct.TemplateWithDefault*, %struct.TemplateWithDefault*)* @"??$?_OH@TemplateWithDefault@@QAEXAAU0@@Z" to i8*) }, section ".xdata", comdat
+// CHECK-DAG: @"_CTA2$$T" = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.2 { i32 2, [2 x %eh.CatchableType*] [%eh.CatchableType* @"_CT??_R0$$T@84", %eh.CatchableType* @"_CT??_R0PAX@84"] }, section ".xdata", comdat
+// CHECK-DAG: @"_CT??_R0P6AXXZ@84" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 1, i8* bitcast (%rtti.TypeDescriptor7* @"??_R0P6AXXZ@8" to i8*), i32 0, i32 -1, i32 0, i32 4, i8* null }, section ".xdata", comdat
+// CHECK-DAG: @_CTA1P6AXXZ = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.1 { i32 1, [1 x %eh.CatchableType*] [%eh.CatchableType* @"_CT??_R0P6AXXZ@84"] }, section ".xdata", comdat
+// CHECK-DAG: @_TI1P6AXXZ = linkonce_odr unnamed_addr constant %eh.ThrowInfo { i32 0, i8* null, i8* null, i8* bitcast (%eh.CatchableTypeArray.1* @_CTA1P6AXXZ to i8*) }, section ".xdata", comdat
+// CHECK-DAG: @_TIU2PAPFAH = linkonce_odr unnamed_addr constant %eh.ThrowInfo { i32 4, i8* null, i8* null, i8* bitcast (%eh.CatchableTypeArray.2* @_CTA2PAPFAH to i8*) }, section ".xdata", comdat
+// CHECK-DAG: @_CTA2PAPFAH = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.2 { i32 2, [2 x %eh.CatchableType*] [%eh.CatchableType* @"_CT??_R0PAPFAH@84", %eh.CatchableType* @"_CT??_R0PAX@84"] }, section ".xdata", comdat
+// CHECK-DAG: @"_TI1?AUFoo@?A0x{{[^@]*}}@@" = internal unnamed_addr constant %eh.ThrowInfo { i32 0, i8* null, i8* null, i8* bitcast (%eh.CatchableTypeArray.1* @"_CTA1?AUFoo@?A0x{{[^@]*}}@@" to i8*) }, section ".xdata"
+
+
+struct N { ~N(); };
+struct M : private N {};
+struct X {};
+struct Z {};
+struct V : private X {};
+struct W : M, virtual V {};
+struct Y : Z, W, virtual V {};
+
+void f(const Y &y) {
+ // CHECK-LABEL: @"?f@@YAXABUY@@@Z"
+ // CHECK: call x86_thiscallcc %struct.Y* @"??0Y@@QAE@ABU0@@Z"(%struct.Y* %[[mem:.*]], %struct.Y*
+ // CHECK: %[[cast:.*]] = bitcast %struct.Y* %[[mem]] to i8*
+ // CHECK: call void @_CxxThrowException(i8* %[[cast]], %eh.ThrowInfo* @"_TI5?AUY@@")
+ throw y;
+}
+
+void g(const int *const *y) {
+ // CHECK-LABEL: @"?g@@YAXPBQBH@Z"
+ // CHECK: call void @_CxxThrowException(i8* %{{.*}}, %eh.ThrowInfo* @_TIC2PAPBH)
+ throw y;
+}
+
+void h(__unaligned int * __unaligned *y) {
+ // CHECK-LABEL: @"?h@@YAXPFAPFAH@Z"
+ // CHECK: call void @_CxxThrowException(i8* %{{.*}}, %eh.ThrowInfo* @_TIU2PAPFAH)
+ throw y;
+}
+
+struct Default {
+ Default(Default &, int = 42);
+};
+
+// CHECK-LABEL: @"??_ODefault@@QAEXAAU0@@Z"
+// CHECK: %[[src_addr:.*]] = alloca
+// CHECK: %[[this_addr:.*]] = alloca
+// CHECK: store {{.*}} %src, {{.*}} %[[src_addr]], align 4
+// CHECK: store {{.*}} %this, {{.*}} %[[this_addr]], align 4
+// CHECK: %[[this:.*]] = load {{.*}} %[[this_addr]]
+// CHECK: %[[src:.*]] = load {{.*}} %[[src_addr]]
+// CHECK: call x86_thiscallcc {{.*}} @"??0Default@@QAE@AAU0@H@Z"({{.*}} %[[this]], {{.*}} %[[src]], i32 42)
+// CHECK: ret void
+
+void h(Default &d) {
+ throw d;
+}
+
+struct Variadic {
+ Variadic(Variadic &, ...);
+};
+
+void i(Variadic &v) {
+ throw v;
+}
+
+// CHECK-LABEL: @"??_OVariadic@@QAEXAAU0@@Z"
+// CHECK: %[[src_addr:.*]] = alloca
+// CHECK: %[[this_addr:.*]] = alloca
+// CHECK: store {{.*}} %src, {{.*}} %[[src_addr:.*]], align
+// CHECK: store {{.*}} %this, {{.*}} %[[this_addr:.*]], align
+// CHECK: %[[this:.*]] = load {{.*}} %[[this_addr]]
+// CHECK: %[[src:.*]] = load {{.*}} %[[src_addr]]
+// CHECK: call {{.*}} @"??0Variadic@@QAA@AAU0@ZZ"({{.*}} %[[this]], {{.*}} %[[src]])
+// CHECK: ret void
+
+struct TemplateWithDefault {
+ template <typename T>
+ static int f() {
+ return 0;
+ }
+ template <typename T = int>
+ TemplateWithDefault(TemplateWithDefault &, T = f<T>());
+};
+
+void j(TemplateWithDefault &twd) {
+ throw twd;
+}
+
+
+void h() {
+ throw nullptr;
+}
+
+#ifdef STD
+namespace std {
+template <typename T>
+void *__GetExceptionInfo(T);
+}
+#else
+template <typename T>
+void *__GetExceptionInfo(T);
+#endif
+using namespace std;
+
+void *GetExceptionInfo_test0() {
+// CHECK-LABEL: @"?GetExceptionInfo_test0@@YAPAXXZ"
+// CHECK: ret i8* bitcast (%eh.ThrowInfo* @_TI1H to i8*)
+ return __GetExceptionInfo(0);
+}
+
+void *GetExceptionInfo_test1() {
+// CHECK-LABEL: @"?GetExceptionInfo_test1@@YAPAXXZ"
+// CHECK: ret i8* bitcast (%eh.ThrowInfo* @_TI1P6AXXZ to i8*)
+ return __GetExceptionInfo<void (*)()>(&h);
+}
+
+// PR36327: Try an exception type with no linkage.
+namespace { struct Foo { } foo_exc; }
+
+void *GetExceptionInfo_test2() {
+// CHECK-LABEL: @"?GetExceptionInfo_test2@@YAPAXXZ"
+// CHECK: ret i8* bitcast (%eh.ThrowInfo* @"_TI1?AUFoo@?A0x{{[^@]*}}@@" to i8*)
+ return __GetExceptionInfo(foo_exc);
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-thunks.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-thunks.cpp
new file mode 100644
index 0000000..2b0231f
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-thunks.cpp
@@ -0,0 +1,164 @@
+// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 >%t 2>&1
+// RUN: FileCheck --check-prefix=MANGLING %s < %t
+// RUN: FileCheck --check-prefix=XMANGLING %s < %t
+// RUN: FileCheck --check-prefix=CODEGEN %s < %t
+// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -triple=x86_64-pc-win32 2>&1 | FileCheck --check-prefix=MANGLING-X64 %s
+
+void foo(void *);
+
+struct A {
+ virtual ~A();
+ virtual void public_f();
+ // Make sure we don't emit unneeded thunks:
+ // XMANGLING-NOT: @"?public_f@A@@QAEXXZ"
+ protected:
+ virtual void protected_f();
+ private:
+ virtual void private_f();
+};
+
+struct B {
+ virtual ~B();
+ virtual void public_f();
+ protected:
+ virtual void protected_f();
+ private:
+ virtual void private_f();
+};
+
+
+struct C : A, B {
+ C();
+
+ virtual ~C();
+ // MANGLING-DAG: declare {{.*}} @"??1C@@UAE@XZ"({{.*}})
+ // MANGLING-DAG: define {{.*}} @"??_GC@@UAEPAXI@Z"({{.*}})
+ // MANGLING-DAG: define {{.*}} @"??_EC@@W3AEPAXI@Z"({{.*}}) {{.*}} comdat
+ // MANGLING-X64-DAG: declare {{.*}} @"??1C@@UEAA@XZ"({{.*}})
+ // MANGLING-X64-DAG: define {{.*}} @"??_GC@@UEAAPEAXI@Z"({{.*}})
+ // MANGLING-X64-DAG: define {{.*}} @"??_EC@@W7EAAPEAXI@Z"({{.*}}) {{.*}} comdat
+
+ // Overrides public_f() of two subobjects with distinct vfptrs, thus needs a thunk.
+ virtual void public_f();
+ // MANGLING-DAG: @"?public_f@C@@UAEXXZ"
+ // MANGLING-DAG: @"?public_f@C@@W3AEXXZ"
+ // MANGLING-X64-DAG: @"?public_f@C@@UEAAXXZ"
+ // MANGLING-X64-DAG: @"?public_f@C@@W7EAAXXZ"
+ protected:
+ virtual void protected_f();
+ // MANGLING-DAG: @"?protected_f@C@@MAEXXZ"
+ // MANGLING-DAG: @"?protected_f@C@@O3AEXXZ"
+ // MANGLING-X64-DAG: @"?protected_f@C@@MEAAXXZ"
+ // MANGLING-X64-DAG: @"?protected_f@C@@O7EAAXXZ"
+
+ private:
+ virtual void private_f();
+ // MANGLING-DAG: @"?private_f@C@@EAEXXZ"
+ // MANGLING-DAG: @"?private_f@C@@G3AEXXZ"
+ // MANGLING-X64-DAG: @"?private_f@C@@EEAAXXZ"
+ // MANGLING-X64-DAG: @"?private_f@C@@G7EAAXXZ"
+};
+
+C::C() {} // Emits vftable and forces thunk generation.
+
+// CODEGEN-LABEL: define linkonce_odr dso_local x86_thiscallcc i8* @"??_EC@@W3AEPAXI@Z"(%struct.C* %this, i32 %should_call_delete) {{.*}} comdat
+// CODEGEN: getelementptr i8, i8* {{.*}}, i32 -4
+// FIXME: should actually call _EC, not _GC.
+// CODEGEN: call x86_thiscallcc i8* @"??_GC@@UAEPAXI@Z"
+// CODEGEN: ret
+
+// CODEGEN-LABEL: define linkonce_odr dso_local x86_thiscallcc void @"?public_f@C@@W3AEXXZ"(%struct.C*
+// CODEGEN: getelementptr i8, i8* {{.*}}, i32 -4
+// CODEGEN: call x86_thiscallcc void @"?public_f@C@@UAEXXZ"(%struct.C*
+// CODEGEN: ret
+
+void zoo(C* obj) {
+ delete obj;
+}
+
+struct D {
+ virtual B* goo();
+};
+
+struct E : D {
+ E();
+ virtual C* goo();
+ // MANGLING-DAG: @"?goo@E@@UAEPAUC@@XZ"
+ // MANGLING-DAG: @"?goo@E@@QAEPAUB@@XZ"
+ // MANGLING-X64-DAG: @"?goo@E@@UEAAPEAUC@@XZ"
+ // MANGLING-X64-DAG: @"?goo@E@@QEAAPEAUB@@XZ"
+};
+
+E::E() {} // Emits vftable and forces thunk generation.
+
+// CODEGEN-LABEL: define weak_odr dso_local x86_thiscallcc %struct.C* @"?goo@E@@QAEPAUB@@XZ"{{.*}} comdat
+// CODEGEN: call x86_thiscallcc %struct.C* @"?goo@E@@UAEPAUC@@XZ"
+// CODEGEN: getelementptr inbounds i8, i8* {{.*}}, i32 4
+// CODEGEN: ret
+
+struct F : virtual A, virtual B {
+ virtual void own_method();
+ virtual ~F();
+};
+
+F f; // Just make sure we don't crash, e.g. mangling the complete dtor.
+
+struct G : C { };
+
+struct H : E {
+ virtual G* goo();
+ // MANGLING-DAG: @"?goo@H@@UAEPAUG@@XZ"
+ // MANGLING-DAG: @"?goo@H@@QAEPAUB@@XZ"
+ // MANGLING-DAG: @"?goo@H@@QAEPAUC@@XZ"
+ // MANGLING-X64-DAG: @"?goo@H@@UEAAPEAUG@@XZ"
+ // MANGLING-X64-DAG: @"?goo@H@@QEAAPEAUB@@XZ"
+ // MANGLING-X64-DAG: @"?goo@H@@QEAAPEAUC@@XZ"
+};
+
+H h;
+
+struct I : D {
+ I();
+ virtual F* goo();
+};
+
+I::I() {} // Emits vftable and forces thunk generation.
+
+// CODEGEN-LABEL: define weak_odr dso_local x86_thiscallcc %struct.{{[BF]}}* @"?goo@I@@QAEPAUB@@XZ"{{.*}} comdat
+// CODEGEN: %[[ORIG_RET:.*]] = call x86_thiscallcc %struct.F* @"?goo@I@@UAEPAUF@@XZ"
+// CODEGEN: %[[ORIG_RET_i8:.*]] = bitcast %struct.F* %[[ORIG_RET]] to i8*
+// CODEGEN: %[[VBPTR_i8:.*]] = getelementptr inbounds i8, i8* %[[ORIG_RET_i8]], i32 4
+// CODEGEN: %[[VBPTR:.*]] = bitcast i8* %[[VBPTR_i8]] to i32**
+// CODEGEN: %[[VBTABLE:.*]] = load i32*, i32** %[[VBPTR]]
+// CODEGEN: %[[VBASE_OFFSET_PTR:.*]] = getelementptr inbounds i32, i32* %[[VBTABLE]], i32 2
+// CODEGEN: %[[VBASE_OFFSET:.*]] = load i32, i32* %[[VBASE_OFFSET_PTR]]
+// CODEGEN: %[[RES_i8:.*]] = getelementptr inbounds i8, i8* %[[VBPTR_i8]], i32 %[[VBASE_OFFSET]]
+// CODEGEN: %[[RES:.*]] = bitcast i8* %[[RES_i8]] to %struct.F*
+// CODEGEN: phi %struct.F* {{.*}} %[[RES]]
+// CODEGEN: ret %struct.{{[BF]}}*
+
+namespace CrashOnThunksForAttributedType {
+// We used to crash on this because the type of foo is an AttributedType, not
+// FunctionType, and we had to look through the sugar.
+struct A {
+ virtual void __stdcall foo();
+};
+struct B {
+ virtual void __stdcall foo();
+};
+struct C : A, B {
+ virtual void __stdcall foo();
+};
+C c;
+}
+
+namespace {
+struct E : D {
+ E();
+ virtual C* goo();
+};
+E::E() {}
+E e;
+// Class with internal linkage has internal linkage thunks.
+// CODEGEN: define internal x86_thiscallcc %struct.C* @"?goo@E@?A0x{{[^@]*}}@@QAEPAUB@@XZ"
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-try-throw.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-try-throw.cpp
new file mode 100644
index 0000000..1a1e941
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-try-throw.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 -mconstructor-aliases -fcxx-exceptions -fexceptions -fno-rtti -DTRY | FileCheck %s -check-prefix=TRY
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 -mconstructor-aliases -fcxx-exceptions -fexceptions -fno-rtti -DTHROW | FileCheck %s -check-prefix=THROW
+
+// THROW-DAG: @"??_R0H@8" = linkonce_odr global %rtti.TypeDescriptor2 { i8** @"??_7type_info@@6B@", i8* null, [3 x i8] c".H\00" }, comdat
+// THROW-DAG: @"_CT??_R0H@84" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 1, i8* bitcast (%rtti.TypeDescriptor2* @"??_R0H@8" to i8*), i32 0, i32 -1, i32 0, i32 4, i8* null }, section ".xdata", comdat
+// THROW-DAG: @_CTA1H = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.1 { i32 1, [1 x %eh.CatchableType*] [%eh.CatchableType* @"_CT??_R0H@84"] }, section ".xdata", comdat
+// THROW-DAG: @_TI1H = linkonce_odr unnamed_addr constant %eh.ThrowInfo { i32 0, i8* null, i8* null, i8* bitcast (%eh.CatchableTypeArray.1* @_CTA1H to i8*) }, section ".xdata", comdat
+
+void external();
+
+inline void not_emitted() {
+ throw int(13); // no error
+}
+
+int main() {
+ int rv = 0;
+#ifdef TRY
+ try {
+ external(); // TRY: invoke void @"?external@@YAXXZ"
+ } catch (int) {
+ rv = 1;
+ // TRY: catchpad within {{.*}} [%rtti.TypeDescriptor2* @"??_R0H@8", i32 0, i8* null]
+ // TRY: catchret
+ }
+#endif
+#ifdef THROW
+ // THROW: store i32 42, i32* %[[mem_for_throw:.*]], align 4
+ // THROW: %[[cast:.*]] = bitcast i32* %[[mem_for_throw]] to i8*
+ // THROW: call void @_CxxThrowException(i8* %[[cast]], %eh.ThrowInfo* @_TI1H)
+ throw int(42);
+#endif
+ return rv;
+}
+
+#ifdef TRY
+// TRY-LABEL: define dso_local void @"?qual_catch@@YAXXZ"
+void qual_catch() {
+ try {
+ external();
+ } catch (const int *) {
+ }
+ // TRY: catchpad within {{.*}} [%rtti.TypeDescriptor4* @"??_R0PAH@8", i32 1, i8* null]
+ // TRY: catchret
+}
+#endif
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-typeid.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-typeid.cpp
new file mode 100644
index 0000000..a571654
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-typeid.cpp
@@ -0,0 +1,70 @@
+// RUN: %clang_cc1 -emit-llvm -O1 -o - -triple=i386-pc-win32 %s -fexceptions -fcxx-exceptions | FileCheck %s
+
+struct type_info;
+namespace std { using ::type_info; }
+
+struct V { virtual void f(); };
+struct A : virtual V { A(); };
+
+extern A a;
+extern V v;
+extern int b;
+A* fn();
+
+const std::type_info* test0_typeid() { return &typeid(int); }
+// CHECK-LABEL: define dso_local %struct.type_info* @"?test0_typeid@@YAPBUtype_info@@XZ"()
+// CHECK: ret %struct.type_info* bitcast (%rtti.TypeDescriptor2* @"??_R0H@8" to %struct.type_info*)
+
+const std::type_info* test1_typeid() { return &typeid(A); }
+// CHECK-LABEL: define dso_local %struct.type_info* @"?test1_typeid@@YAPBUtype_info@@XZ"()
+// CHECK: ret %struct.type_info* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUA@@@8" to %struct.type_info*)
+
+const std::type_info* test2_typeid() { return &typeid(&a); }
+// CHECK-LABEL: define dso_local %struct.type_info* @"?test2_typeid@@YAPBUtype_info@@XZ"()
+// CHECK: ret %struct.type_info* bitcast (%rtti.TypeDescriptor7* @"??_R0PAUA@@@8" to %struct.type_info*)
+
+const std::type_info* test3_typeid() { return &typeid(*fn()); }
+// CHECK-LABEL: define dso_local %struct.type_info* @"?test3_typeid@@YAPBUtype_info@@XZ"()
+// CHECK: [[CALL:%.*]] = tail call %struct.A* @"?fn@@YAPAUA@@XZ"()
+// CHECK-NEXT: [[CMP:%.*]] = icmp eq %struct.A* [[CALL]], null
+// CHECK-NEXT: br i1 [[CMP]]
+// CHECK: tail call i8* @__RTtypeid(i8* null)
+// CHECK-NEXT: unreachable
+// CHECK: [[THIS:%.*]] = bitcast %struct.A* [[CALL]] to i8*
+// CHECK-NEXT: [[VBTBLP:%.*]] = getelementptr inbounds %struct.A, %struct.A* [[CALL]], i32 0, i32 0
+// CHECK-NEXT: [[VBTBL:%.*]] = load i32*, i32** [[VBTBLP]], align 4
+// CHECK-NEXT: [[VBSLOT:%.*]] = getelementptr inbounds i32, i32* [[VBTBL]], i32 1
+// CHECK-NEXT: [[VBASE_OFFS:%.*]] = load i32, i32* [[VBSLOT]], align 4
+// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[THIS]], i32 [[VBASE_OFFS]]
+// CHECK-NEXT: [[RT:%.*]] = tail call i8* @__RTtypeid(i8* [[ADJ]])
+// CHECK-NEXT: [[RET:%.*]] = bitcast i8* [[RT]] to %struct.type_info*
+// CHECK-NEXT: ret %struct.type_info* [[RET]]
+
+const std::type_info* test4_typeid() { return &typeid(b); }
+// CHECK: define dso_local %struct.type_info* @"?test4_typeid@@YAPBUtype_info@@XZ"()
+// CHECK: ret %struct.type_info* bitcast (%rtti.TypeDescriptor2* @"??_R0H@8" to %struct.type_info*)
+
+const std::type_info* test5_typeid() { return &typeid(v); }
+// CHECK: define dso_local %struct.type_info* @"?test5_typeid@@YAPBUtype_info@@XZ"()
+// CHECK: [[RT:%.*]] = tail call i8* @__RTtypeid(i8* bitcast (%struct.V* @"?v@@3UV@@A" to i8*))
+// CHECK-NEXT: [[RET:%.*]] = bitcast i8* [[RT]] to %struct.type_info*
+// CHECK-NEXT: ret %struct.type_info* [[RET]]
+
+namespace PR26329 {
+struct Polymorphic {
+ virtual ~Polymorphic();
+};
+
+void f(const Polymorphic &poly) {
+ try {
+ throw;
+ } catch (...) {
+ Polymorphic cleanup;
+ typeid(poly);
+ }
+}
+// CHECK-LABEL: define dso_local void @"?f@PR26329@@YAXABUPolymorphic@1@@Z"(
+// CHECK: %[[cs:.*]] = catchswitch within none [label %{{.*}}] unwind to caller
+// CHECK: %[[cp:.*]] = catchpad within %[[cs]] [i8* null, i32 64, i8* null]
+// CHECK: invoke i8* @__RTtypeid(i8* {{.*}}) [ "funclet"(token %[[cp]]) ]
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-vbtables.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-vbtables.cpp
new file mode 100644
index 0000000..ae66020
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-vbtables.cpp
@@ -0,0 +1,541 @@
+// RUN: %clang_cc1 %s -fno-rtti -triple=i386-pc-win32 -emit-llvm -o - | FileCheck %s
+
+// See microsoft-abi-structors.cpp for constructor codegen tests.
+
+namespace Test1 {
+// Classic diamond, fully virtual.
+struct A { int a; };
+struct B : virtual A { int b; };
+struct C : virtual A { int c; };
+struct D : virtual B, virtual C { int d; };
+D d; // Force vbtable emission.
+
+// Layout should be:
+// D: vbptr D
+// int d
+// A: int a
+// B: vbptr B
+// int b
+// C: vbptr C
+// int c
+
+// CHECK-DAG: @"??_8D@Test1@@7B01@@" = linkonce_odr unnamed_addr constant [4 x i32] [i32 0, i32 8, i32 12, i32 20], comdat, align 4
+// CHECK-DAG: @"??_8D@Test1@@7BB@1@@" = {{.*}} [2 x i32] [i32 0, i32 -4]
+// CHECK-DAG: @"??_8D@Test1@@7BC@1@@" = {{.*}} [2 x i32] [i32 0, i32 -12]
+// CHECK-DAG: @"??_8C@Test1@@7B@" = {{.*}} [2 x i32] [i32 0, i32 8]
+// CHECK-DAG: @"??_8B@Test1@@7B@" = {{.*}} [2 x i32] [i32 0, i32 8]
+}
+
+namespace Test2 {
+// Classic diamond, only A is virtual.
+struct A { int a; };
+struct B : virtual A { int b; };
+struct C : virtual A { int c; };
+struct D : B, C { int d; };
+D d; // Force vbtable emission.
+
+// Layout should be:
+// B: vbptr B
+// int b
+// C: vbptr C
+// int c
+// D: int d
+// A: int a
+
+// CHECK-DAG: @"??_8D@Test2@@7BB@1@@" = {{.*}} [2 x i32] [i32 0, i32 20]
+// CHECK-DAG: @"??_8D@Test2@@7BC@1@@" = {{.*}} [2 x i32] [i32 0, i32 12]
+// CHECK-DAG: @"??_8C@Test2@@7B@" = {{.*}} [2 x i32] [i32 0, i32 8]
+// CHECK-DAG: @"??_8B@Test2@@7B@" = {{.*}} [2 x i32] [i32 0, i32 8]
+}
+
+namespace Test3 {
+struct A { int a; };
+struct B { int b; };
+struct C : virtual A, virtual B { int c; };
+C c;
+
+// CHECK-DAG: @"??_8C@Test3@@7B@" = {{.*}} [3 x i32] [i32 0, i32 8, i32 12]
+}
+
+namespace Test4 {
+// Test reusing a vbptr from a non-virtual base.
+struct A { int a; };
+struct B : virtual A { int b; };
+struct C : B, virtual A { int c; };
+C c; // Force vbtable emission.
+
+// CHECK-DAG: @"??_8C@Test4@@7B@" = {{.*}} [2 x i32] [i32 0, i32 12]
+// CHECK-DAG: @"??_8B@Test4@@7B@" = {{.*}} [2 x i32] [i32 0, i32 8]
+}
+
+namespace Test5 {
+// Test multiple base subobjects of the same type when that type has a virtual
+// base.
+struct A { int a; };
+struct B : virtual A { int b; };
+struct C : B { int c; };
+struct D : B, C { int d; };
+D d; // Force vbtable emission.
+
+// CHECK-DAG: @"??_8D@Test5@@7BB@1@@"
+// CHECK-DAG: @"??_8D@Test5@@7BC@1@@"
+// CHECK-DAG: @"??_8C@Test5@@7B@"
+// CHECK-DAG: @"??_8B@Test5@@7B@"
+}
+
+namespace Test6 {
+// Test that we skip unneeded base path component names.
+struct A { int a; };
+struct B : virtual A { int b; };
+struct C : B { int c; };
+struct D : B, C { int d; };
+struct E : D { int e; };
+struct F : E, B, C { int f; };
+struct G : F, virtual E { int g; };
+G g;
+
+// CHECK-DAG: @"??_8G@Test6@@7BB@1@E@1@F@1@@" =
+// CHECK-DAG: @"??_8G@Test6@@7BC@1@E@1@F@1@@" =
+// CHECK-DAG: @"??_8G@Test6@@7BB@1@F@1@@" =
+// CHECK-DAG: @"??_8G@Test6@@7BC@1@F@1@@" =
+// CHECK-DAG: @"??_8G@Test6@@7BB@1@E@1@@" =
+// CHECK-DAG: @"??_8G@Test6@@7BC@1@E@1@@" =
+// CHECK-DAG: @"??_8F@Test6@@7BB@1@E@1@@" = {{.*}} [2 x i32] [i32 0, i32 52]
+// CHECK-DAG: @"??_8F@Test6@@7BC@1@E@1@@" = {{.*}} [2 x i32] [i32 0, i32 44]
+// CHECK-DAG: @"??_8F@Test6@@7BB@1@@" = {{.*}} [2 x i32] [i32 0, i32 24]
+// CHECK-DAG: @"??_8F@Test6@@7BC@1@@" = {{.*}} [2 x i32] [i32 0, i32 16]
+// CHECK-DAG: @"??_8C@Test6@@7B@" = {{.*}} [2 x i32] [i32 0, i32 12]
+// CHECK-DAG: @"??_8B@Test6@@7B@" = {{.*}} [2 x i32] [i32 0, i32 8]
+// CHECK-DAG: @"??_8E@Test6@@7BB@1@@" = {{.*}} [2 x i32] [i32 0, i32 28]
+// CHECK-DAG: @"??_8E@Test6@@7BC@1@@" = {{.*}} [2 x i32] [i32 0, i32 20]
+// CHECK-DAG: @"??_8D@Test6@@7BB@1@@" = {{.*}} [2 x i32] [i32 0, i32 24]
+// CHECK-DAG: @"??_8D@Test6@@7BC@1@@" = {{.*}} [2 x i32] [i32 0, i32 16]
+}
+
+namespace Test7 {
+// Test a non-virtual base which reuses the vbptr of another base.
+struct A { int a; };
+struct B { int b; };
+struct C { int c; };
+struct D : virtual A { int d; };
+struct E : B, D, virtual A, virtual C { int e; };
+E o;
+
+// CHECK-DAG: @"??_8E@Test7@@7B@" = {{.*}} [3 x i32] [i32 0, i32 12, i32 16]
+// CHECK-DAG: @"??_8D@Test7@@7B@" = {{.*}} [2 x i32] [i32 0, i32 8]
+}
+
+namespace Test8 {
+// Test a virtual base which reuses the vbptr of another base.
+struct A { int a; };
+struct B : virtual A { int b; };
+struct C : B { int c; };
+struct D : virtual C { int d; };
+D o;
+
+// CHECK-DAG: @"??_8D@Test8@@7B01@@" = {{.*}} [3 x i32] [i32 0, i32 8, i32 12]
+// CHECK-DAG: @"??_8D@Test8@@7BC@1@@" = {{.*}} [2 x i32] [i32 0, i32 -4]
+// CHECK-DAG: @"??_8C@Test8@@7B@" = {{.*}} [2 x i32] [i32 0, i32 12]
+// CHECK-DAG: @"??_8B@Test8@@7B@" = {{.*}} [2 x i32] [i32 0, i32 8]
+}
+
+namespace Test9 {
+// D has to add to B's vbtable because D has more morally virtual bases than B.
+// D then takes B's vbptr and the vbtable is named for D, not B.
+struct A { int a; };
+struct B : virtual A { int b; };
+struct C : virtual B { int c; };
+struct BB : B { int bb; }; // Indirection =/
+struct D : BB, C { int d; };
+struct E : virtual D { };
+E e;
+
+// CHECK-DAG: @"??_8E@Test9@@7B01@@" =
+// CHECK-DAG: @"??_8E@Test9@@7BD@1@@" =
+// CHECK-DAG: @"??_8E@Test9@@7BC@1@@" =
+// CHECK-DAG: @"??_8E@Test9@@7BB@1@@" =
+// CHECK-DAG: @"??_8D@Test9@@7B@" =
+// CHECK-DAG: @"??_8D@Test9@@7BC@1@@" =
+// CHECK-DAG: @"??_8D@Test9@@7BB@1@@" =
+// CHECK-DAG: @"??_8C@Test9@@7B01@@" =
+// CHECK-DAG: @"??_8C@Test9@@7BB@1@@" =
+// CHECK-DAG: @"??_8BB@Test9@@7B@" =
+// CHECK-DAG: @"??_8B@Test9@@7B@" =
+}
+
+namespace Test10 {
+struct A { int a; };
+struct B { int b; };
+struct C : virtual A { int c; };
+struct D : B, C { int d; };
+D d;
+
+// CHECK-DAG: @"??_8D@Test10@@7B@" =
+// CHECK-DAG: @"??_8C@Test10@@7B@" =
+
+}
+
+namespace Test11 {
+// Typical diamond with an extra single inheritance indirection for B and C.
+struct A { int a; };
+struct B : virtual A { int b; };
+struct C : virtual A { int c; };
+struct D : B { int d; };
+struct E : C { int e; };
+struct F : D, E { int f; };
+F f;
+
+// CHECK-DAG: @"??_8F@Test11@@7BD@1@@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 28]
+// CHECK-DAG: @"??_8F@Test11@@7BE@1@@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 16]
+// CHECK-DAG: @"??_8E@Test11@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 12]
+// CHECK-DAG: @"??_8C@Test11@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 8]
+// CHECK-DAG: @"??_8D@Test11@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 12]
+// CHECK-DAG: @"??_8B@Test11@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 8]
+
+}
+
+namespace Test12 {
+// Another vbptr inside a virtual base.
+struct A { int a; };
+struct B : virtual A { int b; };
+struct C : virtual B { int c; };
+struct D : C, B { int d; };
+struct E : D, C, B { int e; };
+E e;
+
+// CHECK-DAG: @"??_8E@Test12@@7BC@1@D@1@@" =
+// CHECK-DAG: @"??_8E@Test12@@7BB@1@D@1@@" =
+// CHECK-DAG: @"??_8E@Test12@@7BD@1@@" =
+// CHECK-DAG: @"??_8E@Test12@@7BC@1@@" =
+// CHECK-DAG: @"??_8E@Test12@@7BB@1@@" =
+// CHECK-DAG: @"??_8C@Test12@@7B01@@" =
+// CHECK-DAG: @"??_8C@Test12@@7BB@1@@" =
+// CHECK-DAG: @"??_8D@Test12@@7BC@1@@" =
+// CHECK-DAG: @"??_8D@Test12@@7BB@1@@" =
+// CHECK-DAG: @"??_8D@Test12@@7B@" =
+// CHECK-DAG: @"??_8B@Test12@@7B@" =
+}
+
+namespace Test13 {
+struct A { int a; };
+struct B : virtual A { int b; };
+struct C : virtual B { int c; };
+struct D : virtual C { int d; };
+struct E : D, C, B { int e; };
+E e;
+
+// CHECK-DAG: @"??_8E@Test13@@7BD@1@@" =
+// CHECK-DAG: @"??_8E@Test13@@7BC@1@D@1@@" =
+// CHECK-DAG: @"??_8E@Test13@@7BB@1@D@1@@" =
+// CHECK-DAG: @"??_8E@Test13@@7BC@1@@" =
+// CHECK-DAG: @"??_8E@Test13@@7BB@1@@" =
+// CHECK-DAG: @"??_8D@Test13@@7B@" =
+// CHECK-DAG: @"??_8D@Test13@@7BC@1@@" =
+// CHECK-DAG: @"??_8D@Test13@@7BB@1@@" =
+// CHECK-DAG: @"??_8C@Test13@@7B01@@" =
+// CHECK-DAG: @"??_8C@Test13@@7BB@1@@" =
+// CHECK-DAG: @"??_8B@Test13@@7B@" =
+}
+
+namespace Test14 {
+struct A { int a; };
+struct B : virtual A { int b; };
+struct C : virtual B { int c; };
+struct D : virtual C { int d; };
+struct E : D, virtual C, virtual B { int e; };
+E e;
+
+// CHECK-DAG: @"??_8E@Test14@@7B@" =
+// CHECK-DAG: @"??_8E@Test14@@7BC@1@@" =
+// CHECK-DAG: @"??_8E@Test14@@7BB@1@@" =
+// CHECK-DAG: @"??_8D@Test14@@7B@" =
+// CHECK-DAG: @"??_8D@Test14@@7BC@1@@" =
+// CHECK-DAG: @"??_8D@Test14@@7BB@1@@" =
+// CHECK-DAG: @"??_8C@Test14@@7B01@@" =
+// CHECK-DAG: @"??_8C@Test14@@7BB@1@@" =
+// CHECK-DAG: @"??_8B@Test14@@7B@" =
+}
+
+namespace Test15 {
+struct A { int a; };
+struct B : virtual A { int b; };
+struct C : virtual A { int c; };
+struct D : virtual B { int d; };
+struct E : D, C, B { int e; };
+E e;
+
+// CHECK-DAG: @"??_8E@Test15@@7BD@1@@" =
+// CHECK-DAG: @"??_8E@Test15@@7BB@1@D@1@@" =
+// CHECK-DAG: @"??_8E@Test15@@7BC@1@@" =
+// CHECK-DAG: @"??_8E@Test15@@7BB@1@@" =
+// CHECK-DAG: @"??_8C@Test15@@7B@" =
+// CHECK-DAG: @"??_8D@Test15@@7B01@@" =
+// CHECK-DAG: @"??_8D@Test15@@7BB@1@@" =
+// CHECK-DAG: @"??_8B@Test15@@7B@" =
+}
+
+namespace Test16 {
+struct A { int a; };
+struct B : virtual A { int b; };
+struct C : virtual B { int c; }; // ambig
+struct D : virtual C { int d; };
+struct E : virtual D { int e; }; // ambig
+struct F : E, D, C, B { int f; }; // ambig
+F f;
+
+// CHECK-DAG: @"??_8F@Test16@@7BE@1@@" =
+// CHECK-DAG: @"??_8F@Test16@@7BD@1@E@1@@" =
+// CHECK-DAG: @"??_8F@Test16@@7BC@1@E@1@@" =
+// CHECK-DAG: @"??_8F@Test16@@7BB@1@E@1@@" =
+// CHECK-DAG: @"??_8F@Test16@@7BD@1@@" =
+// CHECK-DAG: @"??_8F@Test16@@7BC@1@@" =
+// CHECK-DAG: @"??_8F@Test16@@7BB@1@@" =
+// CHECK-DAG: @"??_8E@Test16@@7B01@@" =
+// CHECK-DAG: @"??_8E@Test16@@7BD@1@@" =
+// CHECK-DAG: @"??_8E@Test16@@7BC@1@@" =
+// CHECK-DAG: @"??_8E@Test16@@7BB@1@@" =
+// CHECK-DAG: @"??_8D@Test16@@7B@" =
+// CHECK-DAG: @"??_8D@Test16@@7BC@1@@" =
+// CHECK-DAG: @"??_8D@Test16@@7BB@1@@" =
+// CHECK-DAG: @"??_8C@Test16@@7B01@@" =
+// CHECK-DAG: @"??_8C@Test16@@7BB@1@@" =
+// CHECK-DAG: @"??_8B@Test16@@7B@" =
+}
+
+namespace Test17 {
+// This test case has an interesting alternating pattern of using "vbtable of B"
+// and "vbtable of C for C". This may be the key to the underlying algorithm.
+struct A { int a; };
+struct B : virtual A { int b; };
+struct C : virtual B { int c; }; // ambig
+struct D : virtual C { int d; };
+struct E : virtual D { int e; }; // ambig
+struct F : virtual E { int f; };
+struct G : virtual F { int g; }; // ambig
+struct H : virtual G { int h; };
+struct I : virtual H { int i; }; // ambig
+struct J : virtual I { int j; };
+struct K : virtual J { int k; }; // ambig
+K k;
+
+// CHECK-DAG: @"??_8K@Test17@@7B01@@" =
+// CHECK-DAG: @"??_8J@Test17@@7B@" =
+// CHECK-DAG: @"??_8I@Test17@@7B01@@" =
+// CHECK-DAG: @"??_8H@Test17@@7B@" =
+// CHECK-DAG: @"??_8G@Test17@@7B01@@" =
+// CHECK-DAG: @"??_8F@Test17@@7B@" =
+// CHECK-DAG: @"??_8E@Test17@@7B01@@" =
+// CHECK-DAG: @"??_8D@Test17@@7B@" =
+// CHECK-DAG: @"??_8C@Test17@@7B01@@" =
+// CHECK-DAG: @"??_8B@Test17@@7B@" =
+}
+
+namespace Test18 {
+struct A { int a; };
+struct B : virtual A { int b; };
+struct C : B { int c; };
+struct D : C, B { int d; };
+struct E : D, C, B { int e; };
+E e;
+
+// CHECK-DAG: @"??_8E@Test18@@7BC@1@D@1@@" =
+// CHECK-DAG: @"??_8E@Test18@@7BB@1@D@1@@" =
+// CHECK-DAG: @"??_8E@Test18@@7BC@1@@" =
+// CHECK-DAG: @"??_8E@Test18@@7BB@1@@" =
+// CHECK-DAG: @"??_8B@Test18@@7B@" =
+// CHECK-DAG: @"??_8C@Test18@@7B@" =
+// CHECK-DAG: @"??_8D@Test18@@7BC@1@@" =
+// CHECK-DAG: @"??_8D@Test18@@7BB@1@@" =
+}
+
+namespace Test19 {
+struct A { int a; };
+struct B : virtual A { int b; };
+struct C : virtual B { int c; };
+struct D : virtual C, virtual B { int d; };
+struct E : virtual D, virtual C, virtual B { int e; };
+E e;
+
+// CHECK-DAG: @"??_8E@Test19@@7B01@@" =
+// CHECK-DAG: @"??_8E@Test19@@7BD@1@@" =
+// CHECK-DAG: @"??_8E@Test19@@7BC@1@@" =
+// CHECK-DAG: @"??_8E@Test19@@7BB@1@@" =
+// CHECK-DAG: @"??_8D@Test19@@7B@" =
+// CHECK-DAG: @"??_8D@Test19@@7BC@1@@" =
+// CHECK-DAG: @"??_8D@Test19@@7BB@1@@" =
+// CHECK-DAG: @"??_8C@Test19@@7B01@@" =
+// CHECK-DAG: @"??_8C@Test19@@7BB@1@@" =
+// CHECK-DAG: @"??_8B@Test19@@7B@" =
+}
+
+namespace Test20 {
+// E has no direct vbases, but it adds to C's vbtable anyway.
+struct A { int a; };
+struct B { int b; };
+struct C : virtual A { int c; };
+struct D : virtual B { int d; };
+struct E : C, D { int e; };
+E f;
+
+// CHECK-DAG: @"??_8E@Test20@@7BC@1@@" = linkonce_odr unnamed_addr constant [3 x i32] [i32 0, i32 20, i32 24]
+// CHECK-DAG: @"??_8E@Test20@@7BD@1@@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 16]
+// CHECK-DAG: @"??_8D@Test20@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 8]
+// CHECK-DAG: @"??_8C@Test20@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 8]
+}
+
+namespace Test21 {
+struct A { int a; };
+struct B : virtual A { int b; };
+struct C : B { int c; };
+struct D : B { int d; };
+struct E : C, D { int e; };
+struct F : virtual E { int f; };
+struct G : E { int g; };
+struct H : F, G { int h; };
+H h;
+
+// CHECK-DAG: @"??_8H@Test21@@7B@" =
+// CHECK-DAG: @"??_8H@Test21@@7BC@1@F@1@@" =
+// CHECK-DAG: @"??_8H@Test21@@7BD@1@F@1@@" =
+// CHECK-DAG: @"??_8H@Test21@@7BC@1@G@1@@" =
+// CHECK-DAG: @"??_8H@Test21@@7BD@1@G@1@@" =
+// CHECK-DAG: @"??_8G@Test21@@7BC@1@@" =
+// CHECK-DAG: @"??_8G@Test21@@7BD@1@@" =
+// CHECK-DAG: @"??_8F@Test21@@7B@" =
+// CHECK-DAG: @"??_8F@Test21@@7BC@1@@" =
+// CHECK-DAG: @"??_8F@Test21@@7BD@1@@" =
+// CHECK-DAG: @"??_8E@Test21@@7BC@1@@" =
+// CHECK-DAG: @"??_8E@Test21@@7BD@1@@" =
+// CHECK-DAG: @"??_8D@Test21@@7B@" =
+// CHECK-DAG: @"??_8B@Test21@@7B@" =
+// CHECK-DAG: @"??_8C@Test21@@7B@" =
+}
+
+namespace Test22 {
+struct A { int a; };
+struct B : virtual A { int b; };
+struct C { int c; };
+struct D : B, virtual C { int d; };
+D d;
+
+// CHECK-DAG: @"??_8D@Test22@@7B@" = linkonce_odr unnamed_addr constant [3 x i32] [i32 0, i32 12, i32 16]
+// CHECK-DAG: @"??_8B@Test22@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 8]
+}
+
+namespace Test23 {
+struct A { int a; };
+struct B : virtual A { int b; };
+struct C { int c; };
+// Note the unusual order of bases. It forces C to be laid out before A.
+struct D : virtual C, B { int d; };
+D d;
+
+// CHECK-DAG: @"??_8D@Test23@@7B@" = linkonce_odr unnamed_addr constant [3 x i32] [i32 0, i32 16, i32 12]
+// CHECK-DAG: @"??_8B@Test23@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 8]
+}
+
+namespace Test24 {
+struct A { int a; };
+struct B : virtual A { int b; };
+struct C { int c; };
+struct D : virtual C, B {
+ virtual void f(); // Issues a vfptr, but the vbptr is still shared with B.
+ int d;
+};
+D d;
+
+// CHECK-DAG: @"??_8D@Test24@@7B@" = linkonce_odr unnamed_addr constant [3 x i32] [i32 0, i32 16, i32 12]
+// CHECK-DAG: @"??_8B@Test24@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 8]
+}
+
+namespace Test25 {
+struct A { int a; };
+struct B : virtual A {
+ virtual void f(); // Issues a vfptr.
+ int b;
+};
+struct C { int c; };
+struct D : virtual C, B { int d; };
+D d;
+
+// CHECK-DAG: @"??_8D@Test25@@7B@" = linkonce_odr unnamed_addr constant [3 x i32] [i32 -4, i32 16, i32 12]
+// CHECK-DAG: @"??_8B@Test25@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 -4, i32 8]
+}
+
+namespace Test26 {
+struct A { int a; };
+struct B { int b; };
+struct C { int c; };
+struct D : virtual A { int d; };
+struct E : virtual B {
+ virtual void foo(); // Issues a vfptr.
+ int e;
+};
+struct F: virtual C, D, E { int f; };
+F f;
+// F reuses the D's vbptr, even though D is laid out after E.
+// CHECK-DAG: @"??_8F@Test26@@7BD@1@@" = linkonce_odr unnamed_addr constant [4 x i32] [i32 0, i32 16, i32 12, i32 20]
+// CHECK-DAG: @"??_8F@Test26@@7BE@1@@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 -4, i32 28]
+}
+
+namespace Test27 {
+// PR17748
+struct A {};
+struct B : virtual A {};
+struct C : virtual B {};
+struct D : C, B {};
+struct E : D {};
+struct F : C, E {};
+struct G : F, D, C, B {};
+G x;
+
+// CHECK-DAG: @"??_8G@Test27@@7BB@1@@" =
+// CHECK-DAG: @"??_8G@Test27@@7BB@1@F@1@@" =
+// CHECK-DAG: @"??_8G@Test27@@7BC@1@@" =
+// CHECK-DAG: @"??_8G@Test27@@7BC@1@D@1@@" =
+// CHECK-DAG: @"??_8G@Test27@@7BC@1@E@1@@" =
+// CHECK-DAG: @"??_8G@Test27@@7BC@1@F@1@@" =
+// CHECK-DAG: @"??_8G@Test27@@7BD@1@@" =
+// CHECK-DAG: @"??_8G@Test27@@7BF@1@@" =
+}
+
+namespace Test28 {
+// PR17748
+struct A {};
+struct B : virtual A {};
+struct C : virtual B {};
+struct D : C, B {};
+struct E : C, D {};
+struct F : virtual E, virtual D, virtual C {};
+F x;
+
+// CHECK-DAG: @"??_8F@Test28@@7B01@@" =
+// CHECK-DAG: @"??_8F@Test28@@7BB@1@@" =
+// CHECK-DAG: @"??_8F@Test28@@7BC@1@@" =
+// CHECK-DAG: @"??_8F@Test28@@7BC@1@D@1@@" =
+// CHECK-DAG: @"??_8F@Test28@@7BC@1@D@1@E@1@@" =
+// CHECK-DAG: @"??_8F@Test28@@7BC@1@E@1@@" =
+// CHECK-DAG: @"??_8F@Test28@@7BD@1@@" =
+// CHECK-DAG: @"??_8F@Test28@@7BE@1@@" =
+}
+
+namespace Test29 {
+struct A {};
+struct B : virtual A {};
+struct C : virtual B {};
+struct D : C {};
+D d;
+
+// CHECK-DAG: @"??_8D@Test29@@7BB@1@@" = linkonce_odr unnamed_addr constant [2 x i32] zeroinitializer
+}
+
+namespace Test30 {
+struct A {};
+template <class> struct B : virtual A {
+ B() {}
+};
+
+extern template class B<int>;
+template B<int>::B();
+// CHECK-DAG: @"??_8?$B@H@Test30@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 4], comdat
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-vftables.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-vftables.cpp
new file mode 100644
index 0000000..f8d26f1
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-vftables.cpp
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 %s -fno-rtti -triple=i386-pc-win32 -fms-extensions -emit-llvm -o - -O1 -disable-llvm-passes | FileCheck %s -check-prefix=NO-RTTI
+// RUN: %clang_cc1 %s -triple=i386-pc-win32 -fms-extensions -emit-llvm -o - -O1 -disable-llvm-passes | FileCheck %s -check-prefix=RTTI
+
+// RTTI-DAG: $"??_7S@@6B@" = comdat largest
+// RTTI-DAG: $"??_7V@@6B@" = comdat largest
+
+struct S {
+ virtual ~S();
+} s;
+
+// RTTI-DAG: [[VTABLE_S:@.*]] = private unnamed_addr constant { [2 x i8*] } { [2 x i8*] [i8* bitcast ({{.*}} @"??_R4S@@6B@" to i8*), i8* bitcast ({{.*}} @"??_GS@@UAEPAXI@Z" to i8*)] }, comdat($"??_7S@@6B@")
+// RTTI-DAG: @"??_7S@@6B@" = unnamed_addr alias i8*, getelementptr inbounds ({ [2 x i8*] }, { [2 x i8*] }* [[VTABLE_S]], i32 0, i32 0, i32 1)
+
+// NO-RTTI-DAG: @"??_7S@@6B@" = linkonce_odr unnamed_addr constant { [1 x i8*] } { [1 x i8*] [i8* bitcast ({{.*}} @"??_GS@@UAEPAXI@Z" to i8*)] }
+
+struct __declspec(dllimport) U {
+ virtual ~U();
+} u;
+
+// RTTI-DAG: [[VTABLE_U:@.*]] = private unnamed_addr constant { [2 x i8*] } { [2 x i8*] [i8* bitcast ({{.*}} @"??_R4U@@6B@" to i8*), i8* bitcast ({{.*}} @"??_GU@@UAEPAXI@Z" to i8*)] }
+// RTTI-DAG: @"??_SU@@6B@" = unnamed_addr alias i8*, getelementptr inbounds ({ [2 x i8*] }, { [2 x i8*] }* [[VTABLE_U]], i32 0, i32 0, i32 1)
+
+// NO-RTTI-DAG: @"??_SU@@6B@" = linkonce_odr unnamed_addr constant { [1 x i8*] } { [1 x i8*] [i8* bitcast ({{.*}} @"??_GU@@UAEPAXI@Z" to i8*)] }
+
+struct __declspec(dllexport) V {
+ virtual ~V();
+} v;
+
+// RTTI-DAG: [[VTABLE_V:@.*]] = private unnamed_addr constant { [2 x i8*] } { [2 x i8*] [i8* bitcast ({{.*}} @"??_R4V@@6B@" to i8*), i8* bitcast ({{.*}} @"??_GV@@UAEPAXI@Z" to i8*)] }, comdat($"??_7V@@6B@")
+// RTTI-DAG: @"??_7V@@6B@" = dllexport unnamed_addr alias i8*, getelementptr inbounds ({ [2 x i8*] }, { [2 x i8*] }* [[VTABLE_V]], i32 0, i32 0, i32 1)
+
+// NO-RTTI-DAG: @"??_7V@@6B@" = weak_odr dllexport unnamed_addr constant { [1 x i8*] } { [1 x i8*] [i8* bitcast ({{.*}} @"??_GV@@UAEPAXI@Z" to i8*)] }
+
+namespace {
+struct W {
+ virtual ~W() {}
+} w;
+}
+// RTTI-DAG: [[VTABLE_W:@.*]] = private unnamed_addr constant { [2 x i8*] } { [2 x i8*] [i8* bitcast ({{.*}} @"??_R4W@?A0x{{[^@]*}}@@6B@" to i8*), i8* bitcast ({{.*}} @"??_GW@?A0x{{[^@]*}}@@UAEPAXI@Z" to i8*)] }
+// RTTI-DAG: @"??_7W@?A0x{{[^@]*}}@@6B@" = internal unnamed_addr alias i8*, getelementptr inbounds ({ [2 x i8*] }, { [2 x i8*] }* [[VTABLE_W]], i32 0, i32 0, i32 1)
+
+// NO-RTTI-DAG: @"??_7W@?A0x{{[^@]*}}@@6B@" = internal unnamed_addr constant { [1 x i8*] } { [1 x i8*] [i8* bitcast ({{.*}} @"??_GW@?A0x{{[^@]*}}@@UAEPAXI@Z" to i8*)] }
+
+struct X {};
+template <class> struct Y : virtual X {
+ Y() {}
+ virtual ~Y();
+};
+
+extern template class Y<int>;
+template Y<int>::Y();
+// RTTI-DAG: [[VTABLE_Y:@.*]] = private unnamed_addr constant { [2 x i8*] } { [2 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"??_R4?$Y@H@@6B@" to i8*), i8* bitcast (i8* (%struct.Y*, i32)* @"??_G?$Y@H@@UAEPAXI@Z" to i8*)] }, comdat($"??_7?$Y@H@@6B@")
+// RTTI-DAG: @"??_7?$Y@H@@6B@" = unnamed_addr alias i8*, getelementptr inbounds ({ [2 x i8*] }, { [2 x i8*] }* [[VTABLE_Y]], i32 0, i32 0, i32 1)
+
+// NO-RTTI-DAG: @"??_7?$Y@H@@6B@" = linkonce_odr unnamed_addr constant { [1 x i8*] } { [1 x i8*] [i8* bitcast (i8* (%struct.Y*, i32)* @"??_G?$Y@H@@UAEPAXI@Z" to i8*)] }, comdat
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp
new file mode 100644
index 0000000..0120299
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp
@@ -0,0 +1,86 @@
+// RUN: %clang_cc1 %s -fno-rtti -triple=i386-pc-win32 -emit-llvm -o - | FileCheck %s
+
+// For now, just make sure x86_64 doesn't crash.
+// RUN: %clang_cc1 %s -fno-rtti -triple=x86_64-pc-win32 -emit-llvm -o %t
+
+struct A {
+ virtual void f();
+};
+
+struct B {
+ virtual void f();
+};
+
+struct C : A, B {};
+
+struct D : virtual C {
+ D();
+ ~D();
+ virtual void f();
+ void g();
+ int xxx;
+};
+
+D::D() {} // Forces vftable emission.
+
+// CHECK-LABEL: define linkonce_odr dso_local x86_thiscallcc void @"?f@D@@$4PPPPPPPM@A@AEXXZ"
+// Note that the vtordisp is applied before really adjusting to D*.
+// CHECK: %[[COERCE_LOAD:.*]] = load %struct.D*, %struct.D** %{{.*}}
+// CHECK: %[[ECX:.*]] = load %struct.D*, %struct.D** %{{.*}}
+// CHECK: %[[ECX_i8:.*]] = bitcast %struct.D* %[[ECX]] to i8*
+// CHECK: %[[VTORDISP_PTR_i8:.*]] = getelementptr inbounds i8, i8* %[[ECX_i8]], i32 -4
+// CHECK: %[[VTORDISP_PTR:.*]] = bitcast i8* %[[VTORDISP_PTR_i8]] to i32*
+// CHECK: %[[VTORDISP:.*]] = load i32, i32* %[[VTORDISP_PTR]]
+// CHECK: %[[VTORDISP_NEG:.*]] = sub i32 0, %[[VTORDISP]]
+// CHECK: %[[ADJUSTED_i8:.*]] = getelementptr i8, i8* %[[ECX_i8]], i32 %[[VTORDISP_NEG]]
+// CHECK: call x86_thiscallcc void @"?f@D@@UAEXXZ"(i8* %[[ADJUSTED_i8]])
+// CHECK: ret void
+
+// CHECK-LABEL: define linkonce_odr dso_local x86_thiscallcc void @"?f@D@@$4PPPPPPPI@3AEXXZ"
+// CHECK: %[[COERCE_LOAD:.*]] = load %struct.D*, %struct.D** %{{.*}}
+// CHECK: %[[ECX:.*]] = load %struct.D*, %struct.D** %{{.*}}
+// CHECK: %[[ECX_i8:.*]] = bitcast %struct.D* %[[ECX]] to i8*
+// CHECK: %[[VTORDISP_PTR_i8:.*]] = getelementptr inbounds i8, i8* %[[ECX_i8]], i32 -8
+// CHECK: %[[VTORDISP_PTR:.*]] = bitcast i8* %[[VTORDISP_PTR_i8]] to i32*
+// CHECK: %[[VTORDISP:.*]] = load i32, i32* %[[VTORDISP_PTR]]
+// CHECK: %[[VTORDISP_NEG:.*]] = sub i32 0, %[[VTORDISP]]
+// CHECK: %[[VTORDISP_ADJUSTED_i8:.*]] = getelementptr i8, i8* %[[ECX_i8]], i32 %[[VTORDISP_NEG]]
+// CHECK: %[[ADJUSTED_i8:.*]] = getelementptr i8, i8* %[[VTORDISP_ADJUSTED_i8]], i32 -4
+// CHECK: call x86_thiscallcc void @"?f@D@@UAEXXZ"(i8* %[[ADJUSTED_i8]])
+// CHECK: ret void
+
+struct E : virtual A {
+ virtual void f();
+ ~E();
+};
+
+struct F {
+ virtual void z();
+};
+
+struct G : virtual F, virtual E {
+ int ggg;
+ G();
+ ~G();
+};
+
+G::G() {} // Forces vftable emission.
+
+// CHECK-LABEL: define linkonce_odr dso_local x86_thiscallcc void @"?f@E@@$R4BA@M@PPPPPPPM@7AEXXZ"(i8*
+// CHECK: %[[COERCE_LOAD:.*]] = load %struct.E*, %struct.E** %{{.*}}
+// CHECK: %[[ECX:.*]] = load %struct.E*, %struct.E** %{{.*}}
+// CHECK: %[[ECX_i8:.*]] = bitcast %struct.E* %[[ECX]] to i8*
+// CHECK: %[[VTORDISP_PTR_i8:.*]] = getelementptr inbounds i8, i8* %[[ECX_i8]], i32 -4
+// CHECK: %[[VTORDISP_PTR:.*]] = bitcast i8* %[[VTORDISP_PTR_i8]] to i32*
+// CHECK: %[[VTORDISP:.*]] = load i32, i32* %[[VTORDISP_PTR]]
+// CHECK: %[[VTORDISP_NEG:.*]] = sub i32 0, %[[VTORDISP]]
+// CHECK: %[[VTORDISP_ADJUSTED_i8:.*]] = getelementptr i8, i8* %[[ECX_i8]], i32 %[[VTORDISP_NEG]]
+// CHECK: %[[VBPTR_i8:.*]] = getelementptr inbounds i8, i8* %[[VTORDISP_ADJUSTED_i8]], i32 -16
+// CHECK: %[[VBPTR:.*]] = bitcast i8* %[[VBPTR_i8]] to i32**
+// CHECK: %[[VBTABLE:.*]] = load i32*, i32** %[[VBPTR]]
+// CHECK: %[[VBOFFSET_PTR:.*]] = getelementptr inbounds i32, i32* %[[VBTABLE]], i32 3
+// CHECK: %[[VBASE_OFFSET:.*]] = load i32, i32* %[[VBOFFSET_PTR]]
+// CHECK: %[[VBASE:.*]] = getelementptr inbounds i8, i8* %[[VBPTR_i8]], i32 %[[VBASE_OFFSET]]
+// CHECK: %[[ARG_i8:.*]] = getelementptr i8, i8* %[[VBASE]], i32 8
+// CHECK: call x86_thiscallcc void @"?f@E@@UAEXXZ"(i8* %[[ARG_i8]])
+// CHECK: ret void
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
new file mode 100644
index 0000000..212c8dc
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
@@ -0,0 +1,557 @@
+// RUN: %clang_cc1 %s -fno-rtti -std=c++11 -Wno-inaccessible-base -triple=i386-pc-win32 -emit-llvm -o %t
+// RUN: FileCheck %s < %t
+// RUN: FileCheck --check-prefix=CHECK2 %s < %t
+
+// For now, just make sure x86_64 doesn't crash.
+// RUN: %clang_cc1 %s -fno-rtti -std=c++11 -Wno-inaccessible-base -triple=x86_64-pc-win32 -emit-llvm -o %t
+
+struct VBase {
+ virtual ~VBase();
+ virtual void foo();
+ virtual void bar();
+ int field;
+};
+
+struct B : virtual VBase {
+ B();
+ virtual ~B();
+ virtual void foo();
+ virtual void bar();
+};
+
+B::B() {
+ // CHECK-LABEL: define dso_local x86_thiscallcc %struct.B* @"??0B@@QAE@XZ"
+ // CHECK: %[[THIS:.*]] = load %struct.B*, %struct.B**
+ // CHECK: br i1 %{{.*}}, label %[[INIT_VBASES:.*]], label %[[SKIP_VBASES:.*]]
+
+ // Don't check the INIT_VBASES case as it's covered by the ctor tests.
+
+ // CHECK: %[[SKIP_VBASES]]
+ // CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
+ // CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 0
+ // ...
+ // CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
+ // CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 %{{.*}}
+ // CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to i32 (...)***
+ // CHECK: store i32 (...)** bitcast ({ [3 x i8*] }* @"??_7B@@6B@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
+
+ // Initialize vtorDisp:
+ // CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
+ // CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 0
+ // ...
+ // CHECK: %[[VBASE_OFFSET:.*]] = add nsw i32 0, %{{.*}}
+ // CHECK: %[[VTORDISP_VAL:.*]] = sub i32 %[[VBASE_OFFSET]], 8
+ // CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
+ // CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 %[[VBASE_OFFSET]]
+ // CHECK: %[[VTORDISP_i8:.*]] = getelementptr i8, i8* %[[VBASE_i8]], i32 -4
+ // CHECK: %[[VTORDISP_PTR:.*]] = bitcast i8* %[[VTORDISP_i8]] to i32*
+ // CHECK: store i32 %[[VTORDISP_VAL]], i32* %[[VTORDISP_PTR]]
+
+ // CHECK: ret
+}
+
+B::~B() {
+ // CHECK-LABEL: define dso_local x86_thiscallcc void @"??1B@@UAE@XZ"
+ // Store initial this:
+ // CHECK: %[[THIS_ADDR:.*]] = alloca %struct.B*
+ // CHECK: store %struct.B* %{{.*}}, %struct.B** %[[THIS_ADDR]], align 4
+ // Reload and adjust the this parameter:
+ // CHECK: %[[THIS_RELOAD:.*]] = load %struct.B*, %struct.B** %[[THIS_ADDR]]
+ // CHECK: %[[THIS_UNADJ_i8:.*]] = bitcast %struct.B* %[[THIS_RELOAD]] to i8*
+ // CHECK: %[[THIS_ADJ_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_UNADJ_i8]], i32 -8
+ // CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_ADJ_i8]] to %struct.B*
+
+ // Restore the vfptr that could have been changed by a subclass.
+ // CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
+ // CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 0
+ // ...
+ // CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
+ // CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 %{{.*}}
+ // CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to i32 (...)***
+ // CHECK: store i32 (...)** bitcast ({ [3 x i8*] }* @"??_7B@@6B@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
+
+ // Initialize vtorDisp:
+ // CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
+ // CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 0
+ // ...
+ // CHECK: %[[VBASE_OFFSET:.*]] = add nsw i32 0, %{{.*}}
+ // CHECK: %[[VTORDISP_VAL:.*]] = sub i32 %[[VBASE_OFFSET]], 8
+ // CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
+ // CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 %[[VBASE_OFFSET]]
+ // CHECK: %[[VTORDISP_i8:.*]] = getelementptr i8, i8* %[[VBASE_i8]], i32 -4
+ // CHECK: %[[VTORDISP_PTR:.*]] = bitcast i8* %[[VTORDISP_i8]] to i32*
+ // CHECK: store i32 %[[VTORDISP_VAL]], i32* %[[VTORDISP_PTR]]
+
+ foo(); // Avoid the "trivial destructor" optimization.
+
+ // CHECK: ret
+
+ // CHECK2-LABEL: define linkonce_odr dso_local x86_thiscallcc void @"??_DB@@QAEXXZ"(%struct.B*
+ // CHECK2: %[[THIS:.*]] = load %struct.B*, %struct.B** {{.*}}
+ // CHECK2: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
+ // CHECK2: %[[B_i8:.*]] = getelementptr i8, i8* %[[THIS_i8]], i32 8
+ // CHECK2: %[[B:.*]] = bitcast i8* %[[B_i8]] to %struct.B*
+ // CHECK2: call x86_thiscallcc void @"??1B@@UAE@XZ"(%struct.B* %[[B]])
+ // CHECK2: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
+ // CHECK2: %[[VBASE_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 8
+ // CHECK2: %[[VBASE:.*]] = bitcast i8* %[[VBASE_i8]] to %struct.VBase*
+ // CHECK2: call x86_thiscallcc void @"??1VBase@@UAE@XZ"(%struct.VBase* %[[VBASE]])
+ // CHECK2: ret
+
+ // CHECK2-LABEL: define linkonce_odr dso_local x86_thiscallcc i8* @"??_GB@@UAEPAXI@Z"
+ // CHECK2: store %struct.B* %{{.*}}, %struct.B** %[[THIS_ADDR:.*]], align 4
+ // CHECK2: %[[THIS:.*]] = load %struct.B*, %struct.B** %[[THIS_ADDR]]
+ // CHECK2: %[[THIS_PARAM_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
+ // CHECK2: %[[THIS_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_PARAM_i8:.*]], i32 -8
+ // CHECK2: %[[THIS:.*]] = bitcast i8* %[[THIS_i8]] to %struct.B*
+ // CHECK2: call x86_thiscallcc void @"??_DB@@QAEXXZ"(%struct.B* %[[THIS]])
+ // ...
+ // CHECK2: ret
+}
+
+void B::foo() {
+// CHECK-LABEL: define dso_local x86_thiscallcc void @"?foo@B@@UAEXXZ"(i8*
+//
+// B::foo gets 'this' cast to VBase* in ECX (i.e. this+8) so we
+// need to adjust 'this' before use.
+//
+// Coerce this to correct type:
+// CHECK: %[[THIS_STORE:.*]] = alloca %struct.B*
+// CHECK: %[[THIS_ADDR:.*]] = alloca %struct.B*
+// CHECK: %[[COERCE_VAL:.*]] = bitcast i8* %{{.*}} to %struct.B*
+// CHECK: store %struct.B* %[[COERCE_VAL]], %struct.B** %[[THIS_STORE]], align 4
+//
+// Store initial this:
+// CHECK: %[[THIS_INIT:.*]] = load %struct.B*, %struct.B** %[[THIS_STORE]]
+// CHECK: store %struct.B* %[[THIS_INIT]], %struct.B** %[[THIS_ADDR]], align 4
+//
+// Reload and adjust the this parameter:
+// CHECK: %[[THIS_RELOAD:.*]] = load %struct.B*, %struct.B** %[[THIS_ADDR]]
+// CHECK: %[[THIS_UNADJ_i8:.*]] = bitcast %struct.B* %[[THIS_RELOAD]] to i8*
+// CHECK: %[[THIS_ADJ_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_UNADJ_i8]], i32 -8
+// CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_ADJ_i8]] to %struct.B*
+
+ field = 42;
+// CHECK: %[[THIS8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
+// CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[THIS8]], i32 0
+// CHECK: %[[VBPTR8:.*]] = bitcast i8* %[[VBPTR]] to i32**
+// CHECK: %[[VBTABLE:.*]] = load i32*, i32** %[[VBPTR8]]
+// CHECK: %[[VBENTRY:.*]] = getelementptr inbounds i32, i32* %[[VBTABLE]], i32 1
+// CHECK: %[[VBOFFSET32:.*]] = load i32, i32* %[[VBENTRY]]
+// CHECK: %[[VBOFFSET:.*]] = add nsw i32 0, %[[VBOFFSET32]]
+// CHECK: %[[THIS8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
+// CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS8]], i32 %[[VBOFFSET]]
+// CHECK: %[[VBASE:.*]] = bitcast i8* %[[VBASE_i8]] to %struct.VBase*
+// CHECK: %[[FIELD:.*]] = getelementptr inbounds %struct.VBase, %struct.VBase* %[[VBASE]], i32 0, i32 1
+// CHECK: store i32 42, i32* %[[FIELD]], align 4
+//
+// CHECK: ret void
+}
+
+void call_vbase_bar(B *obj) {
+// CHECK-LABEL: define dso_local void @"?call_vbase_bar@@YAXPAUB@@@Z"(%struct.B* %obj)
+// CHECK: %[[OBJ:.*]] = load %struct.B
+
+ obj->bar();
+// When calling a vbase's virtual method, one needs to adjust 'this'
+// at the caller site.
+//
+// CHECK: %[[OBJ_i8:.*]] = bitcast %struct.B* %[[OBJ]] to i8*
+// CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 0
+// CHECK: %[[VBPTR8:.*]] = bitcast i8* %[[VBPTR]] to i32**
+// CHECK: %[[VBTABLE:.*]] = load i32*, i32** %[[VBPTR8]]
+// CHECK: %[[VBENTRY:.*]] = getelementptr inbounds i32, i32* %[[VBTABLE]], i32 1
+// CHECK: %[[VBOFFSET32:.*]] = load i32, i32* %[[VBENTRY]]
+// CHECK: %[[VBOFFSET:.*]] = add nsw i32 0, %[[VBOFFSET32]]
+// CHECK: %[[VBASE:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 %[[VBOFFSET]]
+//
+// CHECK: %[[OBJ_i8:.*]] = bitcast %struct.B* %[[OBJ]] to i8*
+// CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 0
+// CHECK: %[[VBPTR8:.*]] = bitcast i8* %[[VBPTR]] to i32**
+// CHECK: %[[VBTABLE:.*]] = load i32*, i32** %[[VBPTR8]]
+// CHECK: %[[VBENTRY:.*]] = getelementptr inbounds i32, i32* %[[VBTABLE]], i32 1
+// CHECK: %[[VBOFFSET32:.*]] = load i32, i32* %[[VBENTRY]]
+// CHECK: %[[VBOFFSET:.*]] = add nsw i32 0, %[[VBOFFSET32]]
+// CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 %[[VBOFFSET]]
+// CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VBASE_i8]] to void (i8*)***
+// CHECK: %[[VFTABLE:.*]] = load void (i8*)**, void (i8*)*** %[[VFPTR]]
+// CHECK: %[[VFUN:.*]] = getelementptr inbounds void (i8*)*, void (i8*)** %[[VFTABLE]], i64 2
+// CHECK: %[[VFUN_VALUE:.*]] = load void (i8*)*, void (i8*)** %[[VFUN]]
+//
+// CHECK: call x86_thiscallcc void %[[VFUN_VALUE]](i8* %[[VBASE]])
+//
+// CHECK: ret void
+}
+
+void delete_B(B *obj) {
+// CHECK-LABEL: define dso_local void @"?delete_B@@YAXPAUB@@@Z"(%struct.B* %obj)
+// CHECK: %[[OBJ:.*]] = load %struct.B
+
+ delete obj;
+// CHECK: %[[OBJ_i8:.*]] = bitcast %struct.B* %[[OBJ]] to i8*
+// CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 0
+// CHECK: %[[VBPTR8:.*]] = bitcast i8* %[[VBPTR]] to i32**
+// CHECK: %[[VBTABLE:.*]] = load i32*, i32** %[[VBPTR8]]
+// CHECK: %[[VBENTRY:.*]] = getelementptr inbounds i32, i32* %[[VBTABLE]], i32 1
+// CHECK: %[[VBOFFSET32:.*]] = load i32, i32* %[[VBENTRY]]
+// CHECK: %[[VBOFFSET:.*]] = add nsw i32 0, %[[VBOFFSET32]]
+// CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 %[[VBOFFSET]]
+// CHECK: %[[VBASE:.*]] = bitcast i8* %[[VBASE_i8]] to %struct.B*
+//
+// CHECK: %[[OBJ_i8:.*]] = bitcast %struct.B* %[[OBJ]] to i8*
+// CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 0
+// CHECK: %[[VBPTR8:.*]] = bitcast i8* %[[VBPTR]] to i32**
+// CHECK: %[[VBTABLE:.*]] = load i32*, i32** %[[VBPTR8]]
+// CHECK: %[[VBENTRY:.*]] = getelementptr inbounds i32, i32* %[[VBTABLE]], i32 1
+// CHECK: %[[VBOFFSET32:.*]] = load i32, i32* %[[VBENTRY]]
+// CHECK: %[[VBOFFSET:.*]] = add nsw i32 0, %[[VBOFFSET32]]
+// CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 %[[VBOFFSET]]
+// CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VBASE_i8]] to i8* (%struct.B*, i32)***
+// CHECK: %[[VFTABLE:.*]] = load i8* (%struct.B*, i32)**, i8* (%struct.B*, i32)*** %[[VFPTR]]
+// CHECK: %[[VFUN:.*]] = getelementptr inbounds i8* (%struct.B*, i32)*, i8* (%struct.B*, i32)** %[[VFTABLE]], i64 0
+// CHECK: %[[VFUN_VALUE:.*]] = load i8* (%struct.B*, i32)*, i8* (%struct.B*, i32)** %[[VFUN]]
+//
+// CHECK: call x86_thiscallcc i8* %[[VFUN_VALUE]](%struct.B* %[[VBASE]], i32 1)
+// CHECK: ret void
+}
+
+void call_complete_dtor() {
+ // CHECK-LABEL: define dso_local void @"?call_complete_dtor@@YAXXZ"
+ B b;
+ // CHECK: call x86_thiscallcc %struct.B* @"??0B@@QAE@XZ"(%struct.B* %[[B:.*]], i32 1)
+ // CHECK-NOT: getelementptr
+ // CHECK: call x86_thiscallcc void @"??_DB@@QAEXXZ"(%struct.B* %[[B]])
+ // CHECK: ret
+}
+
+struct C : B {
+ C();
+ // has an implicit vdtor.
+};
+
+// Used to crash on an assertion.
+C::C() {
+// CHECK-LABEL: define dso_local x86_thiscallcc %struct.C* @"??0C@@QAE@XZ"
+}
+
+namespace multiple_vbases {
+struct A {
+ virtual void a();
+};
+
+struct B {
+ virtual void b();
+};
+
+struct C {
+ virtual void c();
+};
+
+struct D : virtual A, virtual B, virtual C {
+ virtual void a();
+ virtual void b();
+ virtual void c();
+ D();
+};
+
+D::D() {
+ // CHECK-LABEL: define dso_local x86_thiscallcc %"struct.multiple_vbases::D"* @"??0D@multiple_vbases@@QAE@XZ"
+ // Just make sure we emit 3 vtordisps after initializing vfptrs.
+ // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"??_7D@multiple_vbases@@6BA@1@@" to i32 (...)**), i32 (...)*** %{{.*}}
+ // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"??_7D@multiple_vbases@@6BB@1@@" to i32 (...)**), i32 (...)*** %{{.*}}
+ // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"??_7D@multiple_vbases@@6BC@1@@" to i32 (...)**), i32 (...)*** %{{.*}}
+ // ...
+ // CHECK: store i32 %{{.*}}, i32* %{{.*}}
+ // CHECK: store i32 %{{.*}}, i32* %{{.*}}
+ // CHECK: store i32 %{{.*}}, i32* %{{.*}}
+ // CHECK: ret
+}
+}
+
+namespace diamond {
+struct A {
+ A();
+ virtual ~A();
+};
+
+struct B : virtual A {
+ B();
+ ~B();
+};
+
+struct C : virtual A {
+ C();
+ ~C();
+ int c1, c2, c3;
+};
+
+struct Z {
+ int z;
+};
+
+struct D : virtual Z, B, C {
+ D();
+ ~D();
+} d;
+
+D::~D() {
+ // CHECK-LABEL: define dso_local x86_thiscallcc void @"??1D@diamond@@UAE@XZ"(%"struct.diamond::D"*{{.*}})
+ // Store initial this:
+ // CHECK: %[[THIS_ADDR:.*]] = alloca %"struct.diamond::D"*
+ // CHECK: store %"struct.diamond::D"* %{{.*}}, %"struct.diamond::D"** %[[THIS_ADDR]], align 4
+ //
+ // Reload and adjust the this parameter:
+ // CHECK: %[[THIS_RELOAD:.*]] = load %"struct.diamond::D"*, %"struct.diamond::D"** %[[THIS_ADDR]]
+ // CHECK: %[[THIS_UNADJ_i8:.*]] = bitcast %"struct.diamond::D"* %[[THIS_RELOAD]] to i8*
+ // CHECK: %[[THIS_ADJ_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_UNADJ_i8]], i32 -24
+ // CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_ADJ_i8]] to %"struct.diamond::D"*
+ //
+ // CHECK: %[[D_i8:.*]] = bitcast %"struct.diamond::D"* %[[THIS]] to i8*
+ // CHECK: %[[C_i8:.*]] = getelementptr inbounds i8, i8* %[[D_i8]], i32 4
+ // CHECK: %[[C:.*]] = bitcast i8* %[[C_i8]] to %"struct.diamond::C"*
+ // CHECK: %[[C_i8:.*]] = bitcast %"struct.diamond::C"* %[[C]] to i8*
+ // CHECK: %[[ARG_i8:.*]] = getelementptr i8, i8* %{{.*}}, i32 16
+ // FIXME: We might consider changing the dtor this parameter type to i8*.
+ // CHECK: %[[ARG:.*]] = bitcast i8* %[[ARG_i8]] to %"struct.diamond::C"*
+ // CHECK: call x86_thiscallcc void @"??1C@diamond@@UAE@XZ"(%"struct.diamond::C"* %[[ARG]])
+
+ // CHECK: %[[B:.*]] = bitcast %"struct.diamond::D"* %[[THIS]] to %"struct.diamond::B"*
+ // CHECK: %[[B_i8:.*]] = bitcast %"struct.diamond::B"* %[[B]] to i8*
+ // CHECK: %[[ARG_i8:.*]] = getelementptr i8, i8* %[[B_i8]], i32 4
+ // CHECK: %[[ARG:.*]] = bitcast i8* %[[ARG_i8]] to %"struct.diamond::B"*
+ // CHECK: call x86_thiscallcc void @"??1B@diamond@@UAE@XZ"(%"struct.diamond::B"* %[[ARG]])
+ // CHECK: ret void
+}
+
+}
+
+namespace test2 {
+struct A { A(); };
+struct B : virtual A { B() {} };
+struct C : B, A { C() {} };
+
+// PR18435: Order mattered here. We were generating code for the delegating
+// call to B() from C().
+void callC() { C x; }
+
+// CHECK-LABEL: define linkonce_odr dso_local x86_thiscallcc %"struct.test2::C"* @"??0C@test2@@QAE@XZ"
+// CHECK: (%"struct.test2::C"* returned %this, i32 %is_most_derived)
+// CHECK: br i1
+// Virtual bases
+// CHECK: call x86_thiscallcc %"struct.test2::A"* @"??0A@test2@@QAE@XZ"(%"struct.test2::A"* %{{.*}})
+// CHECK: br label
+// Non-virtual bases
+// CHECK: call x86_thiscallcc %"struct.test2::B"* @"??0B@test2@@QAE@XZ"(%"struct.test2::B"* %{{.*}}, i32 0)
+// CHECK: call x86_thiscallcc %"struct.test2::A"* @"??0A@test2@@QAE@XZ"(%"struct.test2::A"* %{{.*}})
+// CHECK: ret
+
+// CHECK2-LABEL: define linkonce_odr dso_local x86_thiscallcc %"struct.test2::B"* @"??0B@test2@@QAE@XZ"
+// CHECK2: (%"struct.test2::B"* returned %this, i32 %is_most_derived)
+// CHECK2: call x86_thiscallcc %"struct.test2::A"* @"??0A@test2@@QAE@XZ"(%"struct.test2::A"* %{{.*}})
+// CHECK2: ret
+
+}
+
+namespace test3 {
+// PR19104: A non-virtual call of a virtual method doesn't use vftable thunks,
+// so requires only static adjustment which is different to the one used
+// for virtual calls.
+struct A {
+ virtual void foo();
+};
+
+struct B : virtual A {
+ virtual void bar();
+};
+
+struct C : virtual A {
+ virtual void foo();
+};
+
+struct D : B, C {
+ virtual void bar();
+ int field; // Laid out between C and A subobjects in D.
+};
+
+void D::bar() {
+ // CHECK-LABEL: define dso_local x86_thiscallcc void @"?bar@D@test3@@UAEXXZ"(%"struct.test3::D"* %this)
+
+ C::foo();
+ // Shouldn't need any vbtable lookups. All we have to do is adjust to C*,
+ // then compensate for the adjustment performed in the C::foo() prologue.
+ // CHECK-NOT: load i8*, i8**
+ // CHECK: %[[OBJ_i8:.*]] = bitcast %"struct.test3::D"* %{{.*}} to i8*
+ // CHECK: %[[C_i8:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 8
+ // CHECK: %[[C:.*]] = bitcast i8* %[[C_i8]] to %"struct.test3::C"*
+ // CHECK: %[[C_i8:.*]] = bitcast %"struct.test3::C"* %[[C]] to i8*
+ // CHECK: %[[ARG:.*]] = getelementptr i8, i8* %[[C_i8]], i32 4
+ // CHECK: call x86_thiscallcc void @"?foo@C@test3@@UAEXXZ"(i8* %[[ARG]])
+ // CHECK: ret
+}
+}
+
+namespace test4{
+// PR19172: We used to merge method vftable locations wrong.
+
+struct A {
+ virtual ~A() {}
+};
+
+struct B {
+ virtual ~B() {}
+};
+
+struct C : virtual A, B {
+ virtual ~C();
+};
+
+void foo(void*);
+
+C::~C() {
+ // CHECK-LABEL: define dso_local x86_thiscallcc void @"??1C@test4@@UAE@XZ"(%"struct.test4::C"* %this)
+
+ // In this case "this" points to the most derived class, so no GEPs needed.
+ // CHECK-NOT: getelementptr
+ // CHECK-NOT: bitcast
+ // CHECK: %[[VFPTR_i8:.*]] = bitcast %"struct.test4::C"* %{{.*}} to i32 (...)***
+ // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"??_7C@test4@@6BB@1@@" to i32 (...)**), i32 (...)*** %[[VFPTR_i8]]
+
+ foo(this);
+ // CHECK: ret
+}
+
+void destroy(C *obj) {
+ // CHECK-LABEL: define dso_local void @"?destroy@test4@@YAXPAUC@1@@Z"(%"struct.test4::C"* %obj)
+
+ delete obj;
+ // CHECK: %[[VPTR:.*]] = bitcast %"struct.test4::C"* %[[OBJ:.*]] to i8* (%"struct.test4::C"*, i32)***
+ // CHECK: %[[VFTABLE:.*]] = load i8* (%"struct.test4::C"*, i32)**, i8* (%"struct.test4::C"*, i32)*** %[[VPTR]]
+ // CHECK: %[[VFTENTRY:.*]] = getelementptr inbounds i8* (%"struct.test4::C"*, i32)*, i8* (%"struct.test4::C"*, i32)** %[[VFTABLE]], i64 0
+ // CHECK: %[[VFUN:.*]] = load i8* (%"struct.test4::C"*, i32)*, i8* (%"struct.test4::C"*, i32)** %[[VFTENTRY]]
+ // CHECK: call x86_thiscallcc i8* %[[VFUN]](%"struct.test4::C"* %[[OBJ]], i32 1)
+ // CHECK: ret
+}
+
+struct D {
+ virtual void d();
+};
+
+// The first non-virtual base doesn't have a vdtor,
+// but "this adjustment" is not needed.
+struct E : D, B, virtual A {
+ virtual ~E();
+};
+
+E::~E() {
+ // CHECK-LABEL: define dso_local x86_thiscallcc void @"??1E@test4@@UAE@XZ"(%"struct.test4::E"* %this)
+
+ // In this case "this" points to the most derived class, so no GEPs needed.
+ // CHECK-NOT: getelementptr
+ // CHECK-NOT: bitcast
+ // CHECK: %[[VFPTR_i8:.*]] = bitcast %"struct.test4::E"* %{{.*}} to i32 (...)***
+ // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"??_7E@test4@@6BD@1@@" to i32 (...)**), i32 (...)*** %[[VFPTR_i8]]
+ foo(this);
+}
+
+void destroy(E *obj) {
+ // CHECK-LABEL: define dso_local void @"?destroy@test4@@YAXPAUE@1@@Z"(%"struct.test4::E"* %obj)
+
+ // CHECK-NOT: getelementptr
+ // CHECK: %[[OBJ_i8:.*]] = bitcast %"struct.test4::E"* %[[OBJ]] to i8*
+ // CHECK: %[[B_i8:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 4
+ // FIXME: in fact, the call should take i8* and the bitcast is redundant.
+ // CHECK: %[[B_as_E:.*]] = bitcast i8* %[[B_i8]] to %"struct.test4::E"*
+ // CHECK: %[[OBJ_i8:.*]] = bitcast %"struct.test4::E"* %[[OBJ:.*]] to i8*
+ // CHECK: %[[B_i8:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 4
+ // CHECK: %[[VPTR:.*]] = bitcast i8* %[[B_i8]] to i8* (%"struct.test4::E"*, i32)***
+ // CHECK: %[[VFTABLE:.*]] = load i8* (%"struct.test4::E"*, i32)**, i8* (%"struct.test4::E"*, i32)*** %[[VPTR]]
+ // CHECK: %[[VFTENTRY:.*]] = getelementptr inbounds i8* (%"struct.test4::E"*, i32)*, i8* (%"struct.test4::E"*, i32)** %[[VFTABLE]], i64 0
+ // CHECK: %[[VFUN:.*]] = load i8* (%"struct.test4::E"*, i32)*, i8* (%"struct.test4::E"*, i32)** %[[VFTENTRY]]
+ // CHECK: call x86_thiscallcc i8* %[[VFUN]](%"struct.test4::E"* %[[B_as_E]], i32 1)
+ delete obj;
+}
+
+}
+
+namespace test5 {
+// PR25370: Don't zero-initialize vbptrs in virtual bases.
+struct A {
+ virtual void f();
+};
+
+struct B : virtual A {
+ int Field;
+};
+
+struct C : B {
+ C();
+};
+
+C::C() : B() {}
+// CHECK-LABEL: define dso_local x86_thiscallcc %"struct.test5::C"* @"??0C@test5@@QAE@XZ"(
+// CHECK: %[[THIS:.*]] = load %"struct.test5::C"*, %"struct.test5::C"**
+// CHECK: br i1 %{{.*}}, label %[[INIT_VBASES:.*]], label %[[SKIP_VBASES:.*]]
+
+// CHECK: %[[SKIP_VBASES]]
+// CHECK: %[[B:.*]] = bitcast %"struct.test5::C"* %[[THIS]] to %"struct.test5::B"*
+// CHECK: %[[B_i8:.*]] = bitcast %"struct.test5::B"* %[[B]] to i8*
+// CHECK: %[[FIELD:.*]] = getelementptr inbounds i8, i8* %[[B_i8]], i32 4
+// CHECK: call void @llvm.memset.p0i8.i32(i8* align 4 %[[FIELD]], i8 0, i32 4, i1 false)
+}
+
+namespace pr27621 {
+// Devirtualization through a static_cast used to make us compute the 'this'
+// adjustment for B::g instead of C::g. When we directly call C::g, 'this' is a
+// B*, and the prologue of C::g will adjust it to a C*.
+struct A { virtual void f(); };
+struct B { virtual void g(); };
+struct C final : A, B {
+ virtual void h();
+ void g() override;
+};
+void callit(C *p) {
+ static_cast<B*>(p)->g();
+}
+// CHECK-LABEL: define dso_local void @"?callit@pr27621@@YAXPAUC@1@@Z"(%"struct.pr27621::C"* %{{.*}})
+// CHECK: %[[B_i8:.*]] = getelementptr i8, i8* %{{.*}}, i32 4
+// CHECK: call x86_thiscallcc void @"?g@C@pr27621@@UAEXXZ"(i8* %[[B_i8]])
+}
+
+namespace test6 {
+class A {};
+class B : virtual A {};
+class C : virtual B {
+ virtual void m_fn1();
+ float field;
+};
+class D : C {
+ D();
+};
+D::D() : C() {}
+// CHECK-LABEL: define dso_local x86_thiscallcc %"class.test6::D"* @"??0D@test6@@AAE@XZ"(
+// CHECK: %[[THIS:.*]] = load %"class.test6::D"*, %"class.test6::D"**
+// CHECK: br i1 %{{.*}}, label %[[INIT_VBASES:.*]], label %[[SKIP_VBASES:.*]]
+
+// CHECK: %[[SKIP_VBASES]]
+// CHECK: %[[C:.*]] = bitcast %"class.test6::D"* %[[THIS]] to %"class.test6::C"*
+// CHECK: %[[C_i8:.*]] = bitcast %"class.test6::C"* %[[C]] to i8*
+// CHECK: %[[FIELD:.*]] = getelementptr inbounds i8, i8* %[[C_i8]], i32 8
+// CHECK: call void @llvm.memset.p0i8.i32(i8* align 4 %[[FIELD]], i8 0, i32 4, i1 false)
+}
+
+namespace pr36921 {
+struct A {
+ virtual ~A() {}
+};
+struct B {
+ virtual ~B() {}
+};
+struct C : virtual B {};
+struct D : virtual A, C {};
+D d;
+// CHECK-LABEL: define linkonce_odr dso_local x86_thiscallcc i8* @"??_GD@pr36921@@UAEPAXI@Z"(
+// CHECK: %[[THIS:.*]] = load %"struct.pr36921::D"*, %"struct.pr36921::D"**
+// CHECK: %[[THIS_UNADJ_i8:.*]] = bitcast %"struct.pr36921::D"* %[[THIS_RELOAD]] to i8*
+// CHECK: %[[THIS_ADJ_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_UNADJ_i8]], i32 -4
+// CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_ADJ_i8]] to %"struct.pr36921::D"*
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-virtual-member-pointers.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-virtual-member-pointers.cpp
new file mode 100644
index 0000000..5ebe612
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-virtual-member-pointers.cpp
@@ -0,0 +1,189 @@
+// RUN: %clang_cc1 -std=c++11 -fno-rtti -emit-llvm -triple=i386-pc-win32 %s -o - | FileCheck %s --check-prefix=CHECK32
+// RUN: %clang_cc1 -std=c++11 -fno-rtti -emit-llvm -triple=x86_64-pc-win32 %s -o - | FileCheck %s --check-prefix=CHECK64
+
+struct S {
+ int x, y, z;
+};
+
+// U is not trivially copyable, and requires inalloca to pass by value.
+struct U {
+ int u;
+ U();
+ ~U();
+ U(const U &);
+};
+
+struct B;
+
+struct C {
+ virtual void foo();
+ virtual int bar(int, double);
+ virtual S baz(int);
+ virtual S qux(U);
+ virtual void thud(...);
+ virtual void (B::*plugh())();
+};
+
+namespace {
+struct D {
+ virtual void foo();
+};
+}
+
+void f() {
+ void (C::*ptr)();
+ ptr = &C::foo;
+ ptr = &C::foo; // Don't crash trying to define the thunk twice :)
+
+ int (C::*ptr2)(int, double);
+ ptr2 = &C::bar;
+
+ S (C::*ptr3)(int);
+ ptr3 = &C::baz;
+
+ void (D::*ptr4)();
+ ptr4 = &D::foo;
+
+ S (C::*ptr5)(U);
+ ptr5 = &C::qux;
+
+ void (C::*ptr6)(...);
+ ptr6 = &C::thud;
+
+ auto ptr7 = &C::plugh;
+
+
+// CHECK32-LABEL: define dso_local void @"?f@@YAXXZ"()
+// CHECK32: store i8* bitcast (void (%struct.C*, ...)* @"??_9C@@$BA@AE" to i8*), i8** %ptr
+// CHECK32: store i8* bitcast (void (%struct.C*, ...)* @"??_9C@@$B3AE" to i8*), i8** %ptr2
+// CHECK32: store i8* bitcast (void (%struct.C*, ...)* @"??_9C@@$B7AE" to i8*), i8** %ptr3
+// CHECK32: store i8* bitcast (void (%"struct.(anonymous namespace)::D"*, ...)* @"??_9D@?A0x{{[^@]*}}@@$BA@AE" to i8*), i8** %ptr4
+// CHECK32: }
+//
+// CHECK64-LABEL: define dso_local void @"?f@@YAXXZ"()
+// CHECK64: store i8* bitcast (void (%struct.C*, ...)* @"??_9C@@$BA@AA" to i8*), i8** %ptr
+// CHECK64: store i8* bitcast (void (%struct.C*, ...)* @"??_9C@@$B7AA" to i8*), i8** %ptr2
+// CHECK64: store i8* bitcast (void (%struct.C*, ...)* @"??_9C@@$BBA@AA" to i8*), i8** %ptr3
+// CHECK64: store i8* bitcast (void (%"struct.(anonymous namespace)::D"*, ...)* @"??_9D@?A0x{{[^@]*}}@@$BA@AA" to i8*), i8** %ptr
+// CHECK64: }
+}
+
+
+// Thunk for calling the 1st virtual function in C with no parameters.
+// CHECK32-LABEL: define linkonce_odr x86_thiscallcc void @"??_9C@@$BA@AE"(%struct.C* %this, ...)
+// CHECK32: #[[ATTR:[0-9]+]]
+// CHECK32-NOT: unnamed_addr
+// CHECK32: comdat
+// CHECK32: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 0
+// CHECK32: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]]
+// CHECK32: musttail call x86_thiscallcc void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...)
+// CHECK32-NEXT: ret void
+// CHECK32: }
+//
+// CHECK64-LABEL: define linkonce_odr void @"??_9C@@$BA@AA"(%struct.C* %this, ...)
+// CHECK64: #[[ATTR:[0-9]+]]
+// CHECK64-NOT: unnamed_addr
+// CHECK64: comdat
+// CHECK64: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 0
+// CHECK64: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]]
+// CHECK64: musttail call void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...)
+// CHECK64-NEXT: ret void
+// CHECK64: }
+
+// Thunk for calling the 2nd virtual function in C, taking int and double as parameters, returning int.
+// CHECK32-LABEL: define linkonce_odr x86_thiscallcc void @"??_9C@@$B3AE"(%struct.C* %this, ...)
+// CHECK32: #[[ATTR]] comdat
+// CHECK32: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 1
+// CHECK32: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]]
+// CHECK32: musttail call x86_thiscallcc void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...)
+// CHECK32-NEXT: ret void
+// CHECK32: }
+//
+// CHECK64-LABEL: define linkonce_odr void @"??_9C@@$B7AA"(%struct.C* %this, ...)
+// CHECK64: #[[ATTR]] comdat
+// CHECK64: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 1
+// CHECK64: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]]
+// CHECK64: musttail call void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...)
+// CHECK64-NEXT: ret void
+// CHECK64: }
+
+// Thunk for calling the 3rd virtual function in C, taking an int parameter, returning a struct.
+// CHECK32-LABEL: define linkonce_odr x86_thiscallcc void @"??_9C@@$B7AE"(%struct.C* %this, ...)
+// CHECK32: #[[ATTR]] comdat
+// CHECK32: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 2
+// CHECK32: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]]
+// CHECK32: musttail call x86_thiscallcc void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...)
+// CHECK32-NEXT: ret void
+// CHECK32: }
+//
+// CHECK64-LABEL: define linkonce_odr void @"??_9C@@$BBA@AA"(%struct.C* %this, ...)
+// CHECK64: #[[ATTR]] comdat
+// CHECK64: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 2
+// CHECK64: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]]
+// CHECK64: musttail call void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...)
+// CHECK64-NEXT: ret void
+// CHECK64: }
+
+// Thunk for calling the virtual function in internal class D.
+// CHECK32-LABEL: define internal x86_thiscallcc void @"??_9D@?A0x{{[^@]*}}@@$BA@AE"(%"struct.(anonymous namespace)::D"* %this, ...)
+// CHECK32: #[[ATTR]]
+// CHECK32: [[VPTR:%.*]] = getelementptr inbounds void (%"struct.(anonymous namespace)::D"*, ...)*, void (%"struct.(anonymous namespace)::D"*, ...)** %{{.*}}, i64 0
+// CHECK32: [[CALLEE:%.*]] = load void (%"struct.(anonymous namespace)::D"*, ...)*, void (%"struct.(anonymous namespace)::D"*, ...)** [[VPTR]]
+// CHECK32: musttail call x86_thiscallcc void (%"struct.(anonymous namespace)::D"*, ...) [[CALLEE]](%"struct.(anonymous namespace)::D"* %{{.*}}, ...)
+// CHECK32-NEXT: ret void
+// CHECK32: }
+//
+// CHECK64-LABEL: define internal void @"??_9D@?A0x{{[^@]*}}@@$BA@AA"(%"struct.(anonymous namespace)::D"* %this, ...)
+// CHECK64: #[[ATTR]]
+// CHECK64: [[VPTR:%.*]] = getelementptr inbounds void (%"struct.(anonymous namespace)::D"*, ...)*, void (%"struct.(anonymous namespace)::D"*, ...)** %{{.*}}, i64 0
+// CHECK64: [[CALLEE:%.*]] = load void (%"struct.(anonymous namespace)::D"*, ...)*, void (%"struct.(anonymous namespace)::D"*, ...)** [[VPTR]]
+// CHECK64: musttail call void (%"struct.(anonymous namespace)::D"*, ...) [[CALLEE]](%"struct.(anonymous namespace)::D"* %{{.*}}, ...)
+// CHECK64-NEXT: ret void
+// CHECK64: }
+
+// Thunk for calling the fourth virtual function in C, taking a struct parameter
+// and returning a struct.
+// CHECK32-LABEL: define linkonce_odr x86_thiscallcc void @"??_9C@@$BM@AE"(%struct.C* %this, ...) {{.*}} comdat
+// CHECK32: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 3
+// CHECK32: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]]
+// CHECK32: musttail call x86_thiscallcc void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...)
+// CHECK32-NEXT: ret void
+// CHECK32: }
+//
+// CHECK64-LABEL: define linkonce_odr void @"??_9C@@$BBI@AA"(%struct.C* %this, ...) {{.*}} comdat
+// CHECK64: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 3
+// CHECK64: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]]
+// CHECK64: musttail call void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...)
+// CHECK64: ret void
+// CHECK64: }
+
+// Thunk for calling the fifth virtual function in C which uses the __cdecl calling convention.
+// CHECK32-LABEL: define linkonce_odr void @"??_9C@@$BBA@AA"(%struct.C* %this, ...) {{.*}} comdat align 2 {
+// CHECK32: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 4
+// CHECK32: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]]
+// CHECK32: musttail call void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...)
+// CHECK32: ret void
+// CHECK32: }
+//
+// CHECK64-LABEL: define linkonce_odr void @"??_9C@@$BCA@AA"(%struct.C* %this, ...) {{.*}} comdat align 2 {
+// CHECK64: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 4
+// CHECK64: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]]
+// CHECK64: musttail call void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...)
+// CHECK64: ret void
+// CHECK64: }
+
+// CHECK32: define linkonce_odr x86_thiscallcc void @"??_9C@@$BBE@AE"(%struct.C* %this, ...) {{.*}} comdat align 2 {
+// CHECK32: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 5
+// CHECK32: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]]
+// CHECK32: musttail call x86_thiscallcc void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...)
+// CHECK32: ret void
+// CHECK32: }
+
+// CHECK64: define linkonce_odr void @"??_9C@@$BCI@AA"(%struct.C* %this, ...) {{.*}} comdat align 2 {
+// CHECK64: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 5
+// CHECK64: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]]
+// CHECK64: musttail call void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...)
+// CHECK64: ret void
+// CHECK64: }
+
+// CHECK32: #[[ATTR]] = {{{.*}}"thunk"{{.*}}}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-vmemptr-conflicts.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-vmemptr-conflicts.cpp
new file mode 100644
index 0000000..607ec81
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-vmemptr-conflicts.cpp
@@ -0,0 +1,101 @@
+// RUN: %clang_cc1 -fno-rtti -emit-llvm -triple=i386-pc-win32 %s -o - | FileCheck %s
+
+// In each test case, we have two member pointers whose thunks have the same
+// vtable offset and same mangling, but their prototypes conflict. The
+// arguments and return type may differ. Therefore, we have to bitcast the
+// function prototype. Unfortunately, if the return types differ, LLVM's
+// optimizers can get upset.
+
+namespace num_params {
+struct A { virtual void a(int); };
+struct B { virtual void b(int, int); };
+struct C : A, B {
+ virtual void a(int);
+ virtual void b(int, int);
+};
+void f(C *c) {
+ (c->*(&C::a))(0);
+ (c->*(&C::b))(0, 0);
+}
+}
+
+// CHECK-LABEL: define dso_local void @"?f@num_params@@YAXPAUC@1@@Z"(%"struct.num_params::C"* %c)
+// CHECK: call x86_thiscallcc void bitcast (void (%"struct.num_params::C"*, ...)* @"??_9C@num_params@@$BA@AE" to void (%"struct.num_params::C"*, i32)*)(%"struct.num_params::C"* %{{.*}}, i32 0)
+// CHECK: call x86_thiscallcc void bitcast (void (%"struct.num_params::C"*, ...)* @"??_9C@num_params@@$BA@AE" to void (%"struct.num_params::C"*, i32, i32)*)(%"struct.num_params::C"* %{{.*}}, i32 0, i32 0)
+
+// CHECK-LABEL: define linkonce_odr x86_thiscallcc void @"??_9C@num_params@@$BA@AE"(%"struct.num_params::C"* %this, ...) {{.*}} comdat
+// CHECK: musttail call x86_thiscallcc void (%"struct.num_params::C"*, ...) %{{.*}}(%"struct.num_params::C"* %{{.*}}, ...)
+// CHECK-NEXT: ret void
+
+namespace i64_return {
+struct A { virtual int a(); };
+struct B { virtual long long b(); };
+struct C : A, B {
+ virtual int a();
+ virtual long long b();
+};
+long long f(C *c) {
+ int x = (c->*(&C::a))();
+ long long y = (c->*(&C::b))();
+ return x + y;
+}
+}
+
+// CHECK-LABEL: define dso_local i64 @"?f@i64_return@@YA_JPAUC@1@@Z"(%"struct.i64_return::C"* %c)
+// CHECK: call x86_thiscallcc i32 bitcast (void (%"struct.i64_return::C"*, ...)* @"??_9C@i64_return@@$BA@AE" to i32 (%"struct.i64_return::C"*)*)(%"struct.i64_return::C"* %{{.*}})
+// CHECK: call x86_thiscallcc i64 bitcast (void (%"struct.i64_return::C"*, ...)* @"??_9C@i64_return@@$BA@AE" to i64 (%"struct.i64_return::C"*)*)(%"struct.i64_return::C"* %{{.*}})
+
+// CHECK-LABEL: define linkonce_odr x86_thiscallcc void @"??_9C@i64_return@@$BA@AE"(%"struct.i64_return::C"* %this, ...) {{.*}} comdat
+// CHECK: musttail call x86_thiscallcc void (%"struct.i64_return::C"*, ...) %{{.*}}(%"struct.i64_return::C"* %{{.*}}, ...)
+// CHECK-NEXT: ret void
+
+namespace sret {
+struct Big { int big[32]; };
+struct A { virtual int a(); };
+struct B { virtual Big b(); };
+struct C : A, B {
+ virtual int a();
+ virtual Big b();
+};
+void f(C *c) {
+ (c->*(&C::a))();
+ Big b((c->*(&C::b))());
+}
+}
+
+// CHECK-LABEL: define dso_local void @"?f@sret@@YAXPAUC@1@@Z"(%"struct.sret::C"* %c)
+// CHECK: call x86_thiscallcc i32 bitcast (void (%"struct.sret::C"*, ...)* @"??_9C@sret@@$BA@AE" to i32 (%"struct.sret::C"*)*)(%"struct.sret::C"* %{{.*}})
+// CHECK: call x86_thiscallcc void bitcast (void (%"struct.sret::C"*, ...)* @"??_9C@sret@@$BA@AE" to void (%"struct.sret::C"*, %"struct.sret::Big"*)*)(%"struct.sret::C"* %{{.*}}, %"struct.sret::Big"* sret %{{.*}})
+
+// CHECK-LABEL: define linkonce_odr x86_thiscallcc void @"??_9C@sret@@$BA@AE"(%"struct.sret::C"* %this, ...) {{.*}} comdat
+// CHECK: musttail call x86_thiscallcc void (%"struct.sret::C"*, ...) %{{.*}}(%"struct.sret::C"* %{{.*}}, ...)
+// CHECK-NEXT: ret void
+
+namespace cdecl_inalloca {
+// Fairly evil, since now we end up doing an inalloca-style call through a
+// thunk that doesn't use inalloca. Hopefully the stacks line up?
+struct Big {
+ Big();
+ ~Big();
+ int big[32];
+};
+struct A { virtual void __cdecl a(); };
+struct B { virtual void __cdecl b(Big); };
+struct C : A, B {
+ virtual void __cdecl a();
+ virtual void __cdecl b(Big);
+};
+void f(C *c) {
+ Big b;
+ (c->*(&C::a))();
+ ((c->*(&C::b))(b));
+}
+}
+
+// CHECK-LABEL: define dso_local void @"?f@cdecl_inalloca@@YAXPAUC@1@@Z"(%"struct.cdecl_inalloca::C"* %c)
+// CHECK: call void bitcast (void (%"struct.cdecl_inalloca::C"*, ...)* @"??_9C@cdecl_inalloca@@$BA@AA" to void (%"struct.cdecl_inalloca::C"*)*)(%"struct.cdecl_inalloca::C"* %{{.*}})
+// CHECK: call void bitcast (void (%"struct.cdecl_inalloca::C"*, ...)* @"??_9C@cdecl_inalloca@@$BA@AA" to void (<{ %"struct.cdecl_inalloca::C"*, %"struct.cdecl_inalloca::Big" }>*)*)(<{ %"struct.cdecl_inalloca::C"*, %"struct.cdecl_inalloca::Big" }>* inalloca %{{.*}})
+
+// CHECK-LABEL: define linkonce_odr void @"??_9C@cdecl_inalloca@@$BA@AA"(%"struct.cdecl_inalloca::C"* %this, ...) {{.*}} comdat
+// CHECK: musttail call void (%"struct.cdecl_inalloca::C"*, ...) %{{.*}}(%"struct.cdecl_inalloca::C"* %{{.*}}, ...)
+// CHECK-NEXT: ret void
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-vmemptr-fastcall.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-vmemptr-fastcall.cpp
new file mode 100644
index 0000000..59e8b0b
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-vmemptr-fastcall.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fms-extensions -triple i686-pc-windows-msvc %s -emit-llvm -o - | FileCheck %s
+
+struct A {
+ virtual void __fastcall f(int a, int b);
+};
+void (__fastcall A::*doit())(int, int) {
+ return &A::f;
+}
+
+// CHECK: define linkonce_odr x86_fastcallcc void @"??_9A@@$BA@AI"(%struct.A* inreg %this, ...) {{.*}} comdat align 2 {
+// CHECK: [[VPTR:%.*]] = getelementptr inbounds void (%struct.A*, ...)*, void (%struct.A*, ...)** %{{.*}}, i64 0
+// CHECK: [[CALLEE:%.*]] = load void (%struct.A*, ...)*, void (%struct.A*, ...)** [[VPTR]]
+// CHECK: musttail call x86_fastcallcc void (%struct.A*, ...) [[CALLEE]](%struct.A* inreg %{{.*}}, ...)
+// CHECK: ret void
+// CHECK: }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-vmemptr-vbase.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-vmemptr-vbase.cpp
new file mode 100644
index 0000000..972428a
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-vmemptr-vbase.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fno-rtti -emit-llvm -triple=i386-pc-win32 -fms-extensions -fms-compatibility -std=c++11 %s -o - | FileCheck %s
+
+namespace PR23452 {
+struct A {
+ virtual void f();
+};
+struct B : virtual A {
+ virtual void f();
+};
+void (B::*MemPtr)(void) = &B::f;
+// CHECK-DAG: @"?MemPtr@PR23452@@3P8B@1@AEXXZQ21@" = dso_local global { i8*, i32, i32 } { i8* bitcast ({{.*}} @"??_9B@PR23452@@$BA@AE" to i8*), i32 0, i32 4 }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-vtables-ambiguous.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-vtables-ambiguous.cpp
new file mode 100644
index 0000000..c05fc17
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-vtables-ambiguous.cpp
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 %s -emit-llvm-only -triple=i386-pc-win32 -verify -DTEST1
+// RUN: %clang_cc1 %s -emit-llvm-only -triple=i386-pc-win32 -verify -DTEST2
+
+#ifdef TEST1
+struct A {
+ virtual A *foo(); // in vftable slot #0.
+ virtual A *bar(); // in vftable slot #1.
+};
+
+struct B : virtual A {
+ // appended to the A subobject's vftable in slot #2.
+ virtual B *foo(); // expected-note{{covariant thunk required by 'foo'}}
+};
+
+struct C : virtual A {
+ // appended to the A subobject's vftable in slot #2.
+ virtual C *bar(); // expected-note{{covariant thunk required by 'bar'}}
+};
+
+struct D : B, C { D(); }; // expected-error{{ambiguous vftable component}}
+D::D() {}
+#endif
+
+#ifdef TEST2
+struct A {
+ virtual A *foo(); // in vftable slot #0
+};
+
+struct B : virtual A {
+ // appended to the A subobject's vftable in slot #1.
+ virtual B *foo(); // expected-note{{covariant thunk required by 'foo'}}
+};
+
+struct C : virtual A {
+ // appended to the A subobject's vftable in slot #1.
+ virtual C *foo(); // expected-note{{covariant thunk required by 'foo'}}
+};
+
+struct D : B, C { // expected-error{{ambiguous vftable component}}
+ virtual D *foo();
+ D();
+};
+D::D() {}
+#endif
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-no-thunks.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-no-thunks.cpp
new file mode 100644
index 0000000..62289e4
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-no-thunks.cpp
@@ -0,0 +1,302 @@
+// RUN: %clang_cc1 %s -fno-rtti -triple=i386-pc-win32 -emit-llvm -o %t.ll -fdump-vtable-layouts >%t
+// RUN: FileCheck %s < %t
+// RUN: FileCheck --check-prefix=MANGLING %s < %t.ll
+
+namespace test1 {
+struct A {
+ virtual void f();
+};
+
+struct B {
+ virtual void g();
+ // Add an extra virtual method so it's easier to check for the absence of thunks.
+ virtual void h();
+};
+
+struct X : A, B {
+ // CHECK-LABEL: VFTable for 'test1::A' in 'test1::X' (1 entry)
+ // CHECK-NEXT: 0 | void test1::X::f()
+
+ // CHECK-LABEL: VFTable for 'test1::B' in 'test1::X' (2 entries)
+ // CHECK-NEXT: 0 | void test1::B::g()
+ // CHECK-NEXT: 1 | void test1::B::h()
+
+ // CHECK-LABEL: VFTable indices for 'test1::X' (1 entry)
+ // CHECK-NEXT: 0 | void test1::X::f()
+
+ // MANGLING-DAG: @"??_7X@test1@@6BA@1@@"
+ // MANGLING-DAG: @"??_7X@test1@@6BB@1@@"
+
+ // Overrides only the left child's method (A::f), needs no thunks.
+ virtual void f();
+} x;
+
+void build_vftable(X *obj) { obj->f(); }
+}
+
+namespace test2 {
+struct A {
+ virtual void f();
+};
+
+struct B {
+ virtual void g();
+ virtual void h();
+};
+
+struct X : A, B {
+ // CHECK-LABEL: VFTable for 'test2::A' in 'test2::X' (1 entry)
+ // CHECK-NEXT: 0 | void test2::A::f()
+
+ // CHECK-LABEL: VFTable for 'test2::B' in 'test2::X' (2 entries)
+ // CHECK-NEXT: 0 | void test2::X::g()
+ // CHECK-NEXT: 1 | void test2::B::h()
+
+ // CHECK-LABEL: VFTable indices for 'test2::X' (1 entry).
+ // CHECK-NEXT: via vfptr at offset 4
+ // CHECK-NEXT: 0 | void test2::X::g()
+
+ // Overrides only the right child's method (B::g), needs this adjustment but
+ // not thunks.
+ virtual void g();
+};
+
+void build_vftable(X *obj) { obj->g(); }
+}
+
+namespace test3 {
+struct A {
+ virtual void f();
+};
+
+struct B {
+ virtual void g();
+ virtual void h();
+};
+
+struct X : A, B {
+ // CHECK-LABEL: VFTable for 'test3::A' in 'test3::X' (2 entries)
+ // CHECK-NEXT: 0 | void test3::A::f()
+ // CHECK-NEXT: 1 | void test3::X::i()
+
+ // CHECK-LABEL: VFTable for 'test3::B' in 'test3::X' (2 entries)
+ // CHECK-NEXT: 0 | void test3::B::g()
+ // CHECK-NEXT: 1 | void test3::B::h()
+
+ // CHECK-LABEL: VFTable indices for 'test3::X' (1 entry).
+ // CHECK-NEXT: 1 | void test3::X::i()
+
+ // Only adds a new method.
+ virtual void i();
+};
+
+void build_vftable(X *obj) { obj->i(); }
+}
+
+namespace test4 {
+struct A {
+ virtual void f();
+};
+
+struct Empty { }; // Doesn't have a vftable!
+
+// Only the right base has a vftable, so it's laid out before the left one!
+struct X : Empty, A {
+ // CHECK-LABEL: VFTable for 'test4::A' in 'test4::X' (1 entry)
+ // CHECK-NEXT: 0 | void test4::X::f()
+
+ // CHECK-LABEL: VFTable indices for 'test4::X' (1 entry).
+ // CHECK-NEXT: 0 | void test4::X::f()
+
+ // MANGLING-DAG: @"??_7X@test4@@6B@"
+
+ virtual void f();
+} x;
+
+void build_vftable(X *obj) { obj->f(); }
+}
+
+namespace test5 {
+struct A {
+ virtual void f();
+};
+
+struct B {
+ virtual void g();
+ virtual void h();
+};
+
+struct C : A, B {
+ virtual void f();
+};
+
+struct X : C {
+ // CHECK-LABEL: VFTable for 'test5::A' in 'test5::C' in 'test5::X' (1 entry).
+ // CHECK-NEXT: 0 | void test5::X::f()
+
+ // CHECK-LABEL: VFTable for 'test5::B' in 'test5::C' in 'test5::X' (2 entries).
+ // CHECK-NEXT: 0 | void test5::B::g()
+ // CHECK-NEXT: 1 | void test5::B::h()
+
+ // CHECK-LABEL: VFTable indices for 'test5::X' (1 entry).
+ // CHECK-NEXT: 0 | void test5::X::f()
+
+ // MANGLING-DAG: @"??_7X@test5@@6BA@1@@"
+ // MANGLING-DAG: @"??_7X@test5@@6BB@1@@"
+
+ // Overrides both C::f and A::f.
+ virtual void f();
+} x;
+
+void build_vftable(X *obj) { obj->f(); }
+}
+
+namespace test6 {
+struct A {
+ virtual void f();
+};
+
+struct B {
+ virtual void g();
+ virtual void h();
+};
+
+struct C : A, B {
+ virtual void g();
+};
+
+struct X : C {
+ // CHECK-LABEL: VFTable for 'test6::A' in 'test6::C' in 'test6::X' (1 entry).
+ // CHECK-NEXT: 0 | void test6::A::f()
+
+ // CHECK-LABEL: VFTable for 'test6::B' in 'test6::C' in 'test6::X' (2 entries).
+ // CHECK-NEXT: 0 | void test6::X::g()
+ // CHECK-NEXT: 1 | void test6::B::h()
+
+ // CHECK-LABEL: VFTable indices for 'test6::X' (1 entry).
+ // CHECK-NEXT: via vfptr at offset 4
+ // CHECK-NEXT: 0 | void test6::X::g()
+
+ // Overrides both C::g and B::g.
+ virtual void g();
+};
+
+void build_vftable(X *obj) { obj->g(); }
+}
+
+namespace test7 {
+struct A {
+ virtual void f();
+};
+
+struct B {
+ virtual void g();
+ virtual void h();
+};
+
+struct C : A, B {
+ // Only adds a new method.
+ virtual void i();
+};
+
+struct X : C {
+ // CHECK-LABEL: VFTable for 'test7::A' in 'test7::C' in 'test7::X' (2 entries).
+ // CHECK-NEXT: 0 | void test7::A::f()
+ // CHECK-NEXT: 1 | void test7::C::i()
+
+ // CHECK-LABEL: VFTable for 'test7::B' in 'test7::C' in 'test7::X' (2 entries).
+ // CHECK-NEXT: 0 | void test7::X::g()
+ // CHECK-NEXT: 1 | void test7::B::h()
+
+ // CHECK-LABEL: VFTable indices for 'test7::X' (1 entry).
+ // CHECK-NEXT: via vfptr at offset 4
+ // CHECK-NEXT: 0 | void test7::X::g()
+
+ // Overrides grandparent's B::g.
+ virtual void g();
+};
+
+void build_vftable(X *obj) { obj->g(); }
+}
+
+namespace test8 {
+struct A {
+ virtual void f();
+};
+
+struct B : A {
+ virtual void g();
+};
+
+// There are two 'A' subobjects in this class.
+struct X : A, B {
+ // CHECK-LABEL: VFTable for 'test8::A' in 'test8::X' (2 entries).
+ // CHECK-NEXT: 0 | void test8::A::f()
+ // CHECK-NEXT: 1 | void test8::X::h()
+
+ // CHECK-LABEL: VFTable for 'test8::A' in 'test8::B' in 'test8::X' (2 entries).
+ // CHECK-NEXT: 0 | void test8::A::f()
+ // CHECK-NEXT: 1 | void test8::B::g()
+
+ // CHECK-LABEL: VFTable indices for 'test8::X' (1 entry).
+ // CHECK-NEXT: 1 | void test8::X::h()
+
+ // MANGLING-DAG: @"??_7X@test8@@6BA@1@@"
+ // MANGLING-DAG: @"??_7X@test8@@6BB@1@@"
+
+ virtual void h();
+} x;
+
+void build_vftable(X *obj) { obj->h(); }
+}
+
+namespace test9 {
+struct A {
+ virtual void f();
+};
+
+struct B {
+ virtual void g();
+ virtual void h();
+};
+
+struct C : A, B {
+ // Overrides only the left child's method (A::f).
+ virtual void f();
+};
+
+struct D : A, B {
+ // Overrides only the right child's method (B::g).
+ virtual void g();
+};
+
+// 2-level structure with repeating subobject types, but no thunks needed.
+struct X : C, D {
+ // CHECK-LABEL: VFTable for 'test9::A' in 'test9::C' in 'test9::X' (2 entries)
+ // CHECK-NEXT: 0 | void test9::C::f()
+ // CHECK-NEXT: 1 | void test9::X::z()
+
+ // CHECK-LABEL: VFTable for 'test9::B' in 'test9::C' in 'test9::X' (2 entries)
+ // CHECK-NEXT: 0 | void test9::B::g()
+ // CHECK-NEXT: 1 | void test9::B::h()
+
+ // CHECK-LABEL: VFTable for 'test9::A' in 'test9::D' in 'test9::X' (1 entry)
+ // CHECK-NEXT: 0 | void test9::A::f()
+
+ // CHECK-LABEL: VFTable for 'test9::B' in 'test9::D' in 'test9::X' (2 entries)
+ // CHECK-NEXT: 0 | void test9::D::g()
+ // CHECK-NEXT: 1 | void test9::B::h()
+
+ // CHECK-LABEL: VFTable indices for 'test9::X' (1 entry).
+ // CHECK-NEXT: 1 | void test9::X::z()
+
+ // MANGLING-DAG: @"??_7X@test9@@6BA@1@C@1@@"
+ // MANGLING-DAG: @"??_7X@test9@@6BA@1@D@1@@"
+ // MANGLING-DAG: @"??_7X@test9@@6BB@1@C@1@@"
+ // MANGLING-DAG: @"??_7X@test9@@6BB@1@D@1@@"
+
+ virtual void z();
+} x;
+
+void build_vftable(test9::X *obj) { obj->z(); }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-pure-virtual.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-pure-virtual.cpp
new file mode 100644
index 0000000..85022fc
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-pure-virtual.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 %s -fno-rtti -triple=i386-pc-win32 -emit-llvm -o %t.ll -fdump-vtable-layouts >%t
+// RUN: FileCheck %s < %t
+// RUN: FileCheck --check-prefix=MANGLING %s < %t.ll
+
+struct A {
+ virtual void f();
+};
+
+struct B {
+ virtual void g() = 0;
+ virtual void h();
+};
+
+struct C : A, B {
+ // CHECK-LABEL: VFTable for 'A' in 'C' (1 entry)
+ // CHECK-NEXT: 0 | void A::f()
+
+ // CHECK-LABEL: VFTable for 'B' in 'C' (2 entries)
+ // CHECK-NEXT: 0 | void C::g()
+ // CHECK-NEXT: 1 | void B::h()
+
+ // CHECK-LABEL: VFTable indices for 'C' (1 entry).
+ // CHECK-NEXT: via vfptr at offset 4
+ // CHECK-NEXT: 0 | void C::g()
+
+ // MANGLING-DAG: @"??_7C@@6BA@@@"
+ // MANGLING-DAG: @"??_7C@@6BB@@@"
+
+ // Overrides only the right child's method (B::g),
+ // needs this adjustment but not thunks.
+ virtual void g();
+};
+
+C c;
+void build_vftable(C *obj) { obj->g(); }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-return-adjustment.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-return-adjustment.cpp
new file mode 100644
index 0000000..f7b79a9
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-return-adjustment.cpp
@@ -0,0 +1,364 @@
+// RUN: %clang_cc1 %s -fno-rtti -triple=i386-pc-win32 -emit-llvm -o %t.ll -fdump-vtable-layouts >%t
+// RUN: FileCheck %s < %t
+// RUN: FileCheck --check-prefix=MANGLING %s < %t.ll
+
+namespace test1 {
+struct A {
+ virtual void g();
+ // Add an extra virtual method so it's easier to check for the absence of thunks.
+ virtual void h();
+};
+
+struct B {
+ virtual void g();
+};
+
+// Overrides a method of two bases at the same time, thus needing thunks.
+struct C : A, B {
+ virtual void g();
+};
+
+struct D {
+ virtual B* foo();
+ virtual void z();
+};
+
+struct X : D {
+ // CHECK-LABEL: VFTable for 'test1::D' in 'test1::X' (3 entries).
+ // CHECK-NEXT: 0 | test1::C *test1::X::foo()
+ // CHECK-NEXT: [return adjustment (to type 'struct test1::B *'): 4 non-virtual]
+ // CHECK-NEXT: 1 | void test1::D::z()
+ // CHECK-NEXT: 2 | test1::C *test1::X::foo()
+
+ // CHECK-LABEL: Thunks for 'test1::C *test1::X::foo()' (1 entry).
+ // CHECK-NEXT: 0 | [return adjustment (to type 'struct test1::B *'): 4 non-virtual]
+
+ // CHECK-LABEL: VFTable indices for 'test1::X' (1 entry).
+ // CHECK-NEXT: 2 | test1::C *test1::X::foo()
+
+ // MANGLING-DAG: @"??_7X@test1@@6B@"
+
+ virtual C* foo();
+} x;
+
+void build_vftable(X *obj) { obj->foo(); }
+}
+
+namespace test2 {
+struct A {
+ virtual void g();
+ virtual void h();
+};
+
+struct B {
+ virtual void g();
+};
+
+struct C : A, B {
+ virtual void g();
+};
+
+struct D {
+ virtual B* foo();
+ virtual void z();
+};
+
+struct E : D {
+ virtual C* foo();
+};
+
+struct F : C { };
+
+struct X : E {
+ virtual F* foo();
+ // CHECK-LABEL: VFTable for 'test2::D' in 'test2::E' in 'test2::X' (4 entries).
+ // CHECK-NEXT: 0 | test2::F *test2::X::foo()
+ // CHECK-NEXT: [return adjustment (to type 'struct test2::B *'): 4 non-virtual]
+ // CHECK-NEXT: 1 | void test2::D::z()
+ // CHECK-NEXT: 2 | test2::F *test2::X::foo()
+ // CHECK-NEXT: [return adjustment (to type 'struct test2::C *'): 0 non-virtual]
+ // CHECK-NEXT: 3 | test2::F *test2::X::foo()
+
+ // CHECK-LABEL: Thunks for 'test2::F *test2::X::foo()' (2 entries).
+ // CHECK-NEXT: 0 | [return adjustment (to type 'struct test2::C *'): 0 non-virtual]
+ // CHECK-NEXT: 1 | [return adjustment (to type 'struct test2::B *'): 4 non-virtual]
+
+ // CHECK-LABEL: VFTable indices for 'test2::X' (1 entry).
+ // CHECK-NEXT: 3 | test2::F *test2::X::foo()
+};
+
+void build_vftable(X *obj) { obj->foo(); }
+}
+
+namespace test3 {
+struct A {
+ virtual void g();
+ virtual void h();
+};
+
+struct B {
+ virtual void g();
+};
+
+struct C : A, B {
+ virtual void g();
+};
+
+struct D {
+ virtual B* foo();
+ virtual void z();
+};
+
+struct E : D {
+ virtual C* foo();
+};
+
+struct F : A, C { };
+
+struct X : E {
+ // CHECK-LABEL: VFTable for 'test3::D' in 'test3::E' in 'test3::X' (4 entries).
+ // CHECK-NEXT: 0 | test3::F *test3::X::foo()
+ // CHECK-NEXT: [return adjustment (to type 'struct test3::B *'): 8 non-virtual]
+ // CHECK-NEXT: 1 | void test3::D::z()
+ // CHECK-NEXT: 2 | test3::F *test3::X::foo()
+ // CHECK-NEXT: [return adjustment (to type 'struct test3::C *'): 4 non-virtual]
+ // CHECK-NEXT: 3 | test3::F *test3::X::foo()
+
+ // CHECK-LABEL: Thunks for 'test3::F *test3::X::foo()' (2 entries).
+ // CHECK-NEXT: 0 | [return adjustment (to type 'struct test3::C *'): 4 non-virtual]
+ // CHECK-NEXT: 1 | [return adjustment (to type 'struct test3::B *'): 8 non-virtual]
+
+ // CHECK-LABEL: VFTable indices for 'test3::X' (1 entry).
+ // CHECK-NEXT: 3 | test3::F *test3::X::foo()
+
+ virtual F* foo();
+};
+
+void build_vftable(X *obj) { obj->foo(); }
+}
+
+namespace test4 {
+struct A {
+ virtual void g();
+ virtual void h();
+};
+
+struct B {
+ virtual void g();
+};
+
+struct C : A, B {
+ virtual void g();
+};
+
+struct D {
+ virtual B* foo();
+ virtual void z();
+};
+
+struct E : D {
+ virtual C* foo();
+};
+
+struct F : A, C { };
+
+struct X : D, E {
+ // CHECK-LABEL: VFTable for 'test4::D' in 'test4::X' (3 entries).
+ // CHECK-NEXT: 0 | test4::F *test4::X::foo()
+ // CHECK-NEXT: [return adjustment (to type 'struct test4::B *'): 8 non-virtual]
+ // CHECK-NEXT: 1 | void test4::D::z()
+ // CHECK-NEXT: 2 | test4::F *test4::X::foo()
+
+ // CHECK-LABEL: Thunks for 'test4::F *test4::X::foo()' (1 entry).
+ // CHECK-NEXT: 0 | [return adjustment (to type 'struct test4::B *'): 8 non-virtual]
+
+ // CHECK-LABEL: VFTable for 'test4::D' in 'test4::E' in 'test4::X' (4 entries).
+ // CHECK-NEXT: 0 | test4::F *test4::X::foo()
+ // CHECK-NEXT: [return adjustment (to type 'struct test4::B *'): 8 non-virtual]
+ // CHECK-NEXT: [this adjustment: -4 non-virtual]
+ // CHECK-NEXT: 1 | void test4::D::z()
+ // CHECK-NEXT: 2 | test4::F *test4::X::foo()
+ // CHECK-NEXT: [return adjustment (to type 'struct test4::C *'): 4 non-virtual]
+ // CHECK-NEXT: [this adjustment: -4 non-virtual]
+ // CHECK-NEXT: 3 | test4::F *test4::X::foo()
+ // CHECK-NEXT: [return adjustment (to type 'struct test4::F *'): 0 non-virtual]
+ // CHECK-NEXT: [this adjustment: -4 non-virtual]
+
+ // CHECK-LABEL: Thunks for 'test4::F *test4::X::foo()' (3 entries).
+ // CHECK-NEXT: 0 | [return adjustment (to type 'struct test4::F *'): 0 non-virtual]
+ // CHECK-NEXT: [this adjustment: -4 non-virtual]
+ // CHECK-NEXT: 1 | [return adjustment (to type 'struct test4::C *'): 4 non-virtual]
+ // CHECK-NEXT: [this adjustment: -4 non-virtual]
+ // CHECK-NEXT: 2 | [return adjustment (to type 'struct test4::B *'): 8 non-virtual]
+ // CHECK-NEXT: [this adjustment: -4 non-virtual]
+
+ // CHECK-LABEL: VFTable indices for 'test4::X' (1 entry).
+ // CHECK-NEXT: 2 | test4::F *test4::X::foo()
+
+ virtual F* foo();
+};
+
+void build_vftable(X *obj) { obj->foo(); }
+}
+
+namespace test5 {
+struct A {
+ virtual void g();
+ virtual void h();
+};
+
+struct B {
+ virtual void g();
+};
+
+struct C : A, B {
+ virtual void g();
+};
+
+struct D {
+ virtual B* foo();
+ virtual void z();
+};
+
+struct X : A, D {
+ // CHECK-LABEL: VFTable for 'test5::A' in 'test5::X' (2 entries).
+ // CHECK-NEXT: 0 | void test5::A::g()
+ // CHECK-NEXT: 1 | void test5::A::h()
+
+ // CHECK-LABEL: VFTable for 'test5::D' in 'test5::X' (3 entries).
+ // CHECK-NEXT: 0 | test5::C *test5::X::foo()
+ // CHECK-NEXT: [return adjustment (to type 'struct test5::B *'): 4 non-virtual]
+ // CHECK-NEXT: 1 | void test5::D::z()
+ // CHECK-NEXT: 2 | test5::C *test5::X::foo()
+
+ // CHECK-LABEL: Thunks for 'test5::C *test5::X::foo()' (1 entry).
+ // CHECK-NEXT: 0 | [return adjustment (to type 'struct test5::B *'): 4 non-virtual]
+
+ // CHECK-LABEL: VFTable indices for 'test5::X' (1 entry).
+ // CHECK-NEXT: via vfptr at offset 4
+ // CHECK-NEXT: 2 | test5::C *test5::X::foo()
+
+ virtual C* foo();
+};
+
+void build_vftable(X *obj) { obj->foo(); }
+}
+
+namespace test6 {
+struct A {
+ virtual void g();
+ virtual void h();
+};
+
+struct B {
+ virtual void g();
+};
+
+struct C : A, B {
+ virtual void g();
+};
+
+struct D {
+ virtual B* foo();
+ virtual void z();
+};
+
+struct E : A, D {
+ virtual C* foo();
+};
+
+struct F : A, C { };
+
+struct X : E {
+ // CHECK-LABEL: VFTable for 'test6::A' in 'test6::E' in 'test6::X' (2 entries).
+ // CHECK-NEXT: 0 | void test6::A::g()
+ // CHECK-NEXT: 1 | void test6::A::h()
+
+ // CHECK-LABEL: VFTable for 'test6::D' in 'test6::E' in 'test6::X' (4 entries).
+ // CHECK-NEXT: 0 | test6::F *test6::X::foo()
+ // CHECK-NEXT: [return adjustment (to type 'struct test6::B *'): 8 non-virtual]
+ // CHECK-NEXT: 1 | void test6::D::z()
+ // CHECK-NEXT: 2 | test6::F *test6::X::foo()
+ // CHECK-NEXT: [return adjustment (to type 'struct test6::C *'): 4 non-virtual]
+ // CHECK-NEXT: 3 | test6::F *test6::X::foo()
+
+ // CHECK-LABEL: Thunks for 'test6::F *test6::X::foo()' (2 entries).
+ // CHECK-NEXT: 0 | [return adjustment (to type 'struct test6::C *'): 4 non-virtual]
+ // CHECK-NEXT: 1 | [return adjustment (to type 'struct test6::B *'): 8 non-virtual]
+
+ // CHECK-LABEL: VFTable indices for 'test6::X' (1 entry).
+ // CHECK-NEXT: -- accessible via vfptr at offset 4 --
+ // CHECK-NEXT: 3 | test6::F *test6::X::foo()
+
+ virtual F* foo();
+};
+
+void build_vftable(X *obj) { obj->foo(); }
+}
+
+namespace test7 {
+struct A {
+ virtual A *f() = 0;
+};
+struct B {
+ virtual void g();
+};
+struct C : B, A {
+ virtual void g();
+ virtual C *f() = 0;
+ // CHECK-LABEL: VFTable for 'test7::B' in 'test7::C' (1 entry).
+ // CHECK-NEXT: 0 | void test7::C::g()
+
+ // CHECK-LABEL: VFTable for 'test7::A' in 'test7::C' (2 entries).
+ // CHECK-NEXT: 0 | test7::C *test7::C::f() [pure]
+ // CHECK-NEXT: 1 | test7::C *test7::C::f() [pure]
+
+ // No return adjusting thunks needed for pure virtual methods.
+ // CHECK-NOT: Thunks for 'test7::C *test7::C::f()'
+};
+
+void build_vftable(C *obj) { obj->g(); }
+}
+
+namespace pr20444 {
+struct A {
+ virtual A* f();
+};
+struct B {
+ virtual B* f();
+};
+struct C : A, B {
+ virtual C* f();
+ // CHECK-LABEL: VFTable for 'pr20444::A' in 'pr20444::C' (1 entry).
+ // CHECK-NEXT: 0 | pr20444::C *pr20444::C::f()
+
+ // CHECK-LABEL: VFTable for 'pr20444::B' in 'pr20444::C' (2 entries).
+ // CHECK-NEXT: 0 | pr20444::C *pr20444::C::f()
+ // CHECK-NEXT: [return adjustment (to type 'struct pr20444::B *'): 4 non-virtual]
+ // CHECK-NEXT: [this adjustment: -4 non-virtual]
+ // CHECK-NEXT: 1 | pr20444::C *pr20444::C::f()
+ // CHECK-NEXT: [return adjustment (to type 'struct pr20444::C *'): 0 non-virtual]
+ // CHECK-NEXT: [this adjustment: -4 non-virtual]
+};
+
+void build_vftable(C *obj) { obj->f(); }
+
+struct D : C {
+ virtual D* f();
+ // CHECK-LABEL: VFTable for 'pr20444::A' in 'pr20444::C' in 'pr20444::D' (1 entry).
+ // CHECK-NEXT: 0 | pr20444::D *pr20444::D::f()
+
+ // CHECK-LABEL: VFTable for 'pr20444::B' in 'pr20444::C' in 'pr20444::D' (3 entries).
+ // CHECK-NEXT: 0 | pr20444::D *pr20444::D::f()
+ // CHECK-NEXT: [return adjustment (to type 'struct pr20444::B *'): 4 non-virtual]
+ // CHECK-NEXT: [this adjustment: -4 non-virtual]
+ // CHECK-NEXT: 1 | pr20444::D *pr20444::D::f()
+ // CHECK-NEXT: [return adjustment (to type 'struct pr20444::C *'): 0 non-virtual]
+ // CHECK-NEXT: [this adjustment: -4 non-virtual]
+ // CHECK-NEXT: 2 | pr20444::D *pr20444::D::f()
+ // CHECK-NEXT: [return adjustment (to type 'struct pr20444::D *'): 0 non-virtual]
+ // CHECK-NEXT: [this adjustment: -4 non-virtual]
+};
+
+void build_vftable(D *obj) { obj->f(); }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp
new file mode 100644
index 0000000..e34c4d0
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp
@@ -0,0 +1,200 @@
+// RUN: %clang_cc1 %s -fno-rtti -triple=i386-pc-win32 -emit-llvm -o %t.ll -fdump-vtable-layouts >%t
+// RUN: FileCheck %s < %t
+// RUN: FileCheck --check-prefix=BITCODE %s < %t.ll
+
+namespace test1 {
+struct A {
+ virtual void g();
+ // Add an extra virtual method so it's easier to check for the absence of thunks.
+ virtual void h();
+};
+
+struct B {
+ virtual void g(); // Collides with A::g if both are bases of some class.
+};
+
+// Overrides methods of two bases at the same time, thus needing thunks.
+struct X : A, B {
+ // CHECK-LABEL: VFTable for 'test1::A' in 'test1::X' (2 entries).
+ // CHECK-NEXT: 0 | void test1::X::g()
+ // CHECK-NEXT: 1 | void test1::A::h()
+
+ // CHECK-LABEL: VFTable for 'test1::B' in 'test1::X' (1 entry).
+ // CHECK-NEXT: 0 | void test1::X::g()
+ // CHECK-NEXT: [this adjustment: -4 non-virtual]
+
+ // CHECK-LABEL: Thunks for 'void test1::X::g()' (1 entry).
+ // CHECK-NEXT: 0 | [this adjustment: -4 non-virtual]
+
+ // CHECK-LABEL: VFTable indices for 'test1::X' (1 entry).
+ // CHECK-NEXT: 0 | void test1::X::g()
+
+ // BITCODE-DAG: @"??_7X@test1@@6BA@1@@"
+ // BITCODE-DAG: @"??_7X@test1@@6BB@1@@"
+
+ virtual void g();
+} x;
+
+void build_vftable(X *obj) { obj->g(); }
+}
+
+namespace test2 {
+struct A {
+ virtual void f();
+};
+
+struct B {
+ virtual void g();
+ virtual void h();
+};
+
+struct C {
+ virtual void g();
+};
+
+struct X : A, B, C {
+ // CHECK-LABEL: VFTable for 'test2::A' in 'test2::X' (1 entry).
+ // CHECK-NEXT: 0 | void test2::A::f()
+
+ // CHECK-LABEL: VFTable for 'test2::B' in 'test2::X' (2 entries).
+ // CHECK-NEXT: 0 | void test2::X::g()
+ // CHECK-NEXT: 1 | void test2::B::h()
+
+ // CHECK-LABEL: VFTable for 'test2::C' in 'test2::X' (1 entry).
+ // CHECK-NEXT: 0 | void test2::X::g()
+ // CHECK-NEXT: [this adjustment: -4 non-virtual]
+
+ // CHECK-LABEL: Thunks for 'void test2::X::g()' (1 entry).
+ // CHECK-NEXT: 0 | [this adjustment: -4 non-virtual]
+
+ // CHECK-LABEL: VFTable indices for 'test2::X' (1 entry).
+ // CHECK-NEXT: via vfptr at offset 4
+ // CHECK-NEXT: 0 | void test2::X::g()
+
+ // BITCODE-DAG: @"??_7X@test2@@6BA@1@@"
+ // BITCODE-DAG: @"??_7X@test2@@6BB@1@@"
+ // BITCODE-DAG: @"??_7X@test2@@6BC@1@@"
+
+ virtual void g();
+} x;
+
+void build_vftable(X *obj) { obj->g(); }
+}
+
+namespace test3 {
+struct A {
+ virtual void f();
+};
+
+struct B {
+ virtual void g();
+ virtual void h();
+};
+
+struct C: A, B {
+ // Overrides only the left child's method (A::f), needs no thunks.
+ virtual void f();
+};
+
+struct D: A, B {
+ // Overrides only the right child's method (B::g),
+ // needs this adjustment but not thunks.
+ virtual void g();
+};
+
+// Overrides methods of two bases at the same time, thus needing thunks.
+struct X: C, D {
+ // CHECK-LABEL: VFTable for 'test3::A' in 'test3::C' in 'test3::X' (1 entry).
+ // CHECK-NEXT: 0 | void test3::X::f()
+
+ // CHECK-LABEL: VFTable for 'test3::B' in 'test3::C' in 'test3::X' (2 entries).
+ // CHECK-NEXT: 0 | void test3::X::g()
+ // CHECK-NEXT: 1 | void test3::B::h()
+
+ // CHECK-LABEL: VFTable for 'test3::A' in 'test3::D' in 'test3::X' (1 entry).
+ // CHECK-NEXT: 0 | void test3::X::f()
+ // CHECK-NEXT: [this adjustment: -8 non-virtual]
+
+ // CHECK-LABEL: Thunks for 'void test3::X::f()' (1 entry).
+ // CHECK-NEXT: 0 | [this adjustment: -8 non-virtual]
+
+ // CHECK-LABEL: VFTable for 'test3::B' in 'test3::D' in 'test3::X' (2 entries).
+ // CHECK-NEXT: 0 | void test3::X::g()
+ // CHECK-NEXT: [this adjustment: -8 non-virtual]
+ // CHECK-NEXT: 1 | void test3::B::h()
+
+ // CHECK-LABEL: Thunks for 'void test3::X::g()' (1 entry).
+ // CHECK-NEXT: 0 | [this adjustment: -8 non-virtual]
+
+ // CHECK-LABEL: VFTable indices for 'test3::X' (2 entries).
+ // CHECK-NEXT: via vfptr at offset 0
+ // CHECK-NEXT: 0 | void test3::X::f()
+ // CHECK-NEXT: via vfptr at offset 4
+ // CHECK-NEXT: 0 | void test3::X::g()
+
+ virtual void f();
+ virtual void g();
+} x;
+
+void build_vftable(X *obj) { obj->g(); }
+}
+
+namespace test4 {
+struct A {
+ virtual void foo();
+};
+struct B {
+ virtual int filler();
+ virtual int operator-();
+ virtual int bar();
+};
+struct C : public A, public B {
+ virtual int filler();
+ virtual int operator-();
+ virtual int bar();
+};
+
+// BITCODE-LABEL: define {{.*}}"?ffun@test4@@YAXAAUC@1@@Z
+void ffun(C &c) {
+ // BITCODE: [[THIS1:%.+]] = bitcast %"struct.test4::C"* {{.*}} to i8*
+ // BITCODE: [[THIS2:%.+]] = getelementptr inbounds i8, i8* [[THIS1]], i32 4
+ // BITCODE: call x86_thiscallcc {{.*}}(i8* [[THIS2]])
+ c.bar();
+}
+
+// BITCODE-LABEL: define {{.*}}"?fop@test4@@YAXAAUC@1@@Z
+void fop(C &c) {
+ // BITCODE: [[THIS1:%.+]] = bitcast %"struct.test4::C"* {{.*}} to i8*
+ // BITCODE: [[THIS2:%.+]] = getelementptr inbounds i8, i8* [[THIS1]], i32 4
+ // BITCODE: call x86_thiscallcc {{.*}}(i8* [[THIS2]])
+ -c;
+}
+
+}
+
+namespace pr30293 {
+struct NonTrivial {
+ ~NonTrivial();
+ int x;
+};
+struct A { virtual void f(); };
+struct B { virtual void __cdecl g(NonTrivial); };
+struct C final : A, B {
+ void f() override;
+ void __cdecl g(NonTrivial) override;
+};
+C *whatsthis;
+void C::f() { g(NonTrivial()); }
+void C::g(NonTrivial o) {
+ whatsthis = this;
+}
+
+// BITCODE-LABEL: define dso_local void @"?g@C@pr30293@@UAAXUNonTrivial@2@@Z"(<{ i8*, %"struct.pr30293::NonTrivial" }>* inalloca)
+// BITCODE: %[[thisaddr:[^ ]*]] = getelementptr inbounds <{ i8*, %"struct.pr30293::NonTrivial" }>, <{ i8*, %"struct.pr30293::NonTrivial" }>* {{.*}}, i32 0, i32 0
+// BITCODE: %[[thisaddr1:[^ ]*]] = bitcast i8** %[[thisaddr]] to %"struct.pr30293::C"**
+// BITCODE: %[[this1:[^ ]*]] = load %"struct.pr30293::C"*, %"struct.pr30293::C"** %[[thisaddr1]], align 4
+// BITCODE: %[[this2:[^ ]*]] = bitcast %"struct.pr30293::C"* %[[this1]] to i8*
+// BITCODE: %[[this3:[^ ]*]] = getelementptr inbounds i8, i8* %[[this2]], i32 -4
+// BITCODE: %[[this4:[^ ]*]] = bitcast i8* %[[this3]] to %"struct.pr30293::C"*
+// BITCODE: store %"struct.pr30293::C"* %[[this4]], %"struct.pr30293::C"** @"?whatsthis@pr30293@@3PAUC@1@A", align 4
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-vdtors.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-vdtors.cpp
new file mode 100644
index 0000000..a407766
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-vdtors.cpp
@@ -0,0 +1,94 @@
+// RUN: %clang_cc1 %s -fno-rtti -triple=i386-pc-win32 -emit-llvm -o %t.ll -fdump-vtable-layouts >%t
+// RUN: FileCheck %s < %t
+
+struct A {
+ virtual ~A();
+ virtual void z1();
+};
+
+struct B {
+ virtual ~B();
+};
+
+struct C : A, B {
+ // CHECK-LABEL: VFTable for 'A' in 'C' (2 entries).
+ // CHECK-NEXT: 0 | C::~C() [scalar deleting]
+ // CHECK-NEXT: 1 | void A::z1()
+
+ // CHECK-LABEL: VFTable for 'B' in 'C' (1 entry).
+ // CHECK-NEXT: 0 | C::~C() [scalar deleting]
+ // CHECK-NEXT: [this adjustment: -4 non-virtual]
+
+ // CHECK-LABEL: Thunks for 'C::~C()' (1 entry).
+ // CHECK-NEXT: 0 | [this adjustment: -4 non-virtual]
+
+ // CHECK-LABEL: VFTable indices for 'C' (1 entry).
+ // CHECK-NEXT: 0 | C::~C() [scalar deleting]
+ virtual ~C();
+};
+
+void build_vftable(C *obj) { delete obj; }
+
+struct D {
+ // No virtual destructor here!
+ virtual void z4();
+};
+
+struct E : D, B {
+ // Implicit virtual dtor here!
+
+ // CHECK-LABEL: VFTable for 'D' in 'E' (1 entry).
+ // CHECK-NEXT: 0 | void D::z4()
+
+ // CHECK-LABEL: VFTable for 'B' in 'E' (1 entry).
+ // CHECK-NEXT: 0 | E::~E() [scalar deleting]
+ // CHECK-NEXT: [this adjustment: -4 non-virtual]
+
+ // CHECK-LABEL: Thunks for 'E::~E()' (1 entry).
+ // CHECK-NEXT: 0 | [this adjustment: -4 non-virtual]
+
+ // CHECK-LABEL: VFTable indices for 'E' (1 entry).
+ // CHECK-NEXT: -- accessible via vfptr at offset 4 --
+ // CHECK-NEXT: 0 | E::~E() [scalar deleting]
+};
+
+void build_vftable(E *obj) { delete obj; }
+
+struct F : D, B {
+ // Implicit virtual dtor here!
+
+ // CHECK-LABEL: VFTable for 'D' in 'F' (1 entry).
+ // CHECK-NEXT: 0 | void D::z4()
+
+ // CHECK-LABEL: VFTable for 'B' in 'F' (1 entry).
+ // CHECK-NEXT: 0 | F::~F() [scalar deleting]
+ // CHECK-NEXT: [this adjustment: -4 non-virtual]
+
+ // CHECK-LABEL: Thunks for 'F::~F()' (1 entry).
+ // CHECK-NEXT: 0 | [this adjustment: -4 non-virtual]
+
+ // CHECK-LABEL: VFTable indices for 'F' (1 entry).
+ // CHECK-NEXT: -- accessible via vfptr at offset 4 --
+ // CHECK-NEXT: 0 | F::~F() [scalar deleting]
+};
+
+void build_vftable(F *obj) { delete obj; }
+
+struct G : F {
+ // CHECK-LABEL: VFTable for 'D' in 'F' in 'G' (1 entry).
+ // CHECK-NEXT: 0 | void D::z4()
+
+ // CHECK-LABEL: VFTable for 'B' in 'F' in 'G' (1 entry).
+ // CHECK-NEXT: 0 | G::~G() [scalar deleting]
+ // CHECK-NEXT: [this adjustment: -4 non-virtual]
+
+ // CHECK-LABEL: Thunks for 'G::~G()' (1 entry).
+ // CHECK-NEXT: 0 | [this adjustment: -4 non-virtual]
+
+ // CHECK-LABEL: VFTable indices for 'G' (1 entry).
+ // CHECK-NEXT: -- accessible via vfptr at offset 4 --
+ // CHECK-NEXT: 0 | G::~G() [scalar deleting]
+ virtual ~G();
+};
+
+void build_vftable(G *obj) { delete obj; }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-vtables-return-thunks.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-vtables-return-thunks.cpp
new file mode 100644
index 0000000..38e6ed5
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-vtables-return-thunks.cpp
@@ -0,0 +1,218 @@
+// RUN: %clang_cc1 -fno-rtti %s -emit-llvm -o %t -triple=i386-pc-win32 -fdump-vtable-layouts 2>&1 | FileCheck --check-prefix=VFTABLES %s
+// RUN: FileCheck --check-prefix=GLOBALS %s < %t
+// RUN: FileCheck --check-prefix=CODEGEN %s < %t
+
+namespace test1 {
+
+// Some covariant types.
+struct A { int a; };
+struct B { int b; };
+struct C : A, B { int c; };
+struct D : C { int d; };
+struct E : D { int e; };
+
+// One base class and two overrides, all with covariant return types.
+struct H { virtual B *foo(); };
+struct I : H { virtual C *foo(); };
+struct J : I { virtual D *foo(); J(); };
+struct K : J { virtual E *foo(); K(); };
+
+J::J() {}
+
+// VFTABLES-LABEL: VFTable for 'test1::H' in 'test1::I' in 'test1::J' (3 entries).
+// VFTABLES-NEXT: 0 | test1::D *test1::J::foo()
+// VFTABLES-NEXT: [return adjustment (to type 'struct test1::B *'): 4 non-virtual]
+// VFTABLES-NEXT: 1 | test1::D *test1::J::foo()
+// VFTABLES-NEXT: [return adjustment (to type 'struct test1::C *'): 0 non-virtual]
+// VFTABLES-NEXT: 2 | test1::D *test1::J::foo()
+
+// GLOBALS-LABEL: @"??_7J@test1@@6B@" = linkonce_odr unnamed_addr constant { [3 x i8*] }
+// GLOBALS: @"?foo@J@test1@@QAEPAUB@2@XZ"
+// GLOBALS: @"?foo@J@test1@@QAEPAUC@2@XZ"
+// GLOBALS: @"?foo@J@test1@@UAEPAUD@2@XZ"
+
+K::K() {}
+
+// VFTABLES-LABEL: VFTable for 'test1::H' in 'test1::I' in 'test1::J' in 'test1::K' (4 entries).
+// VFTABLES-NEXT: 0 | test1::E *test1::K::foo()
+// VFTABLES-NEXT: [return adjustment (to type 'struct test1::B *'): 4 non-virtual]
+// VFTABLES-NEXT: 1 | test1::E *test1::K::foo()
+// VFTABLES-NEXT: [return adjustment (to type 'struct test1::C *'): 0 non-virtual]
+// VFTABLES-NEXT: 2 | test1::E *test1::K::foo()
+// VFTABLES-NEXT: [return adjustment (to type 'struct test1::D *'): 0 non-virtual]
+// VFTABLES-NEXT: 3 | test1::E *test1::K::foo()
+
+// Only B to C requires adjustment, but we get 3 thunks in K's vftable, two of
+// which are trivial.
+// GLOBALS-LABEL: @"??_7K@test1@@6B@" = linkonce_odr unnamed_addr constant { [4 x i8*] }
+// GLOBALS: @"?foo@K@test1@@QAEPAUB@2@XZ"
+// GLOBALS: @"?foo@K@test1@@QAEPAUC@2@XZ"
+// GLOBALS: @"?foo@K@test1@@QAEPAUD@2@XZ"
+// GLOBALS: @"?foo@K@test1@@UAEPAUE@2@XZ"
+
+// This thunk has a return adjustment.
+// CODEGEN-LABEL: define {{.*}} @"?foo@K@test1@@QAEPAUB@2@XZ"
+// CODEGEN: call {{.*}} @"?foo@K@test1@@UAEPAUE@2@XZ"
+// CODEGEN: icmp {{.*}}, null
+// CODEGEN: getelementptr
+// CODEGEN: ret
+
+// These two don't.
+// CODEGEN-LABEL: define {{.*}} @"?foo@K@test1@@QAEPAUC@2@XZ"
+// CODEGEN: call {{.*}} @"?foo@K@test1@@UAEPAUE@2@XZ"
+// CODEGEN-NEXT: ret
+
+// CODEGEN-LABEL: define {{.*}} @"?foo@K@test1@@QAEPAUD@2@XZ"
+// CODEGEN: call {{.*}} @"?foo@K@test1@@UAEPAUE@2@XZ"
+// CODEGEN-NEXT: ret
+
+}
+
+namespace test2 {
+
+// Covariant types. D* is not trivially convertible to C*.
+struct A { int a; };
+struct B { int b; };
+struct C : B { int c; };
+struct D : A, C { int d; };
+struct E : D { int e; };
+
+// J's foo will require an adjusting thunk, and K will require a trivial thunk.
+struct H { virtual B *foo(); };
+struct I : H { virtual C *foo(); };
+struct J : I { virtual D *foo(); J(); };
+struct K : J { virtual E *foo(); K(); };
+
+J::J() {}
+
+// VFTABLES-LABEL: VFTable for 'test2::H' in 'test2::I' in 'test2::J' (2 entries).
+// VFTABLES-NEXT: 0 | test2::D *test2::J::foo()
+// VFTABLES-NEXT: [return adjustment (to type 'struct test2::B *'): 4 non-virtual]
+// VFTABLES-NEXT: 1 | test2::D *test2::J::foo()
+
+// GLOBALS-LABEL: @"??_7J@test2@@6B@" = linkonce_odr unnamed_addr constant { [2 x i8*] }
+
+K::K() {}
+
+// VFTABLES-LABEL: VFTable for 'test2::H' in 'test2::I' in 'test2::J' in 'test2::K' (3 entries).
+// VFTABLES-NEXT: 0 | test2::E *test2::K::foo()
+// VFTABLES-NEXT: [return adjustment (to type 'struct test2::B *'): 4 non-virtual]
+// VFTABLES-NEXT: 1 | test2::E *test2::K::foo()
+// VFTABLES-NEXT: [return adjustment (to type 'struct test2::D *'): 0 non-virtual]
+// VFTABLES-NEXT: 2 | test2::E *test2::K::foo()
+
+// GLOBALS-LABEL: @"??_7K@test2@@6B@" = linkonce_odr unnamed_addr constant { [3 x i8*] }
+
+}
+
+namespace pr20479 {
+struct A {
+ virtual A *f();
+};
+
+struct B : virtual A {
+ virtual B *f();
+};
+
+struct C : virtual A, B {
+// VFTABLES-LABEL: VFTable for 'pr20479::A' in 'pr20479::B' in 'pr20479::C' (2 entries).
+// VFTABLES-NEXT: 0 | pr20479::B *pr20479::B::f()
+// VFTABLES-NEXT: [return adjustment (to type 'struct pr20479::A *'): vbase #1, 0 non-virtual]
+// VFTABLES-NEXT: 1 | pr20479::B *pr20479::B::f()
+ C();
+};
+
+C::C() {}
+
+// GLOBALS-LABEL: @"??_7C@pr20479@@6B@" = linkonce_odr unnamed_addr constant { [2 x i8*] }
+// GLOBALS: @"?f@B@pr20479@@QAEPAUA@2@XZ"
+// GLOBALS: @"?f@B@pr20479@@UAEPAU12@XZ"
+}
+
+namespace pr21073 {
+struct A {
+ virtual A *f();
+};
+
+struct B : virtual A {
+ virtual B *f();
+};
+
+struct C : virtual A, virtual B {
+// VFTABLES-LABEL: VFTable for 'pr21073::A' in 'pr21073::B' in 'pr21073::C' (2 entries).
+// VFTABLES-NEXT: 0 | pr21073::B *pr21073::B::f()
+// VFTABLES-NEXT: [return adjustment (to type 'struct pr21073::A *'): vbase #1, 0 non-virtual]
+// VFTABLES-NEXT: [this adjustment: 8 non-virtual]
+// VFTABLES-NEXT: 1 | pr21073::B *pr21073::B::f()
+// VFTABLES-NEXT: [return adjustment (to type 'struct pr21073::B *'): 0 non-virtual]
+// VFTABLES-NEXT: [this adjustment: 8 non-virtual]
+ C();
+};
+
+C::C() {}
+
+// GLOBALS-LABEL: @"??_7C@pr21073@@6B@" = linkonce_odr unnamed_addr constant { [2 x i8*] }
+// GLOBALS: @"?f@B@pr21073@@WPPPPPPPI@AEPAUA@2@XZ"
+// GLOBALS: @"?f@B@pr21073@@WPPPPPPPI@AEPAU12@XZ"
+}
+
+namespace pr21073_2 {
+struct A { virtual A *foo(); };
+struct B : virtual A {};
+struct C : virtual A { virtual C *foo(); };
+struct D : B, C { D(); };
+D::D() {}
+
+// VFTABLES-LABEL: VFTable for 'pr21073_2::A' in 'pr21073_2::C' in 'pr21073_2::D' (2 entries)
+// VFTABLES-NEXT: 0 | pr21073_2::C *pr21073_2::C::foo()
+// VFTABLES-NEXT: [return adjustment (to type 'struct pr21073_2::A *'): vbase #1, 0 non-virtual]
+// VFTABLES-NEXT: 1 | pr21073_2::C *pr21073_2::C::foo()
+
+// GLOBALS-LABEL: @"??_7D@pr21073_2@@6B@" = {{.*}} constant { [2 x i8*] }
+// GLOBALS: @"?foo@C@pr21073_2@@QAEPAUA@2@XZ"
+// GLOBALS: @"?foo@C@pr21073_2@@UAEPAU12@XZ"
+}
+
+namespace test3 {
+struct A { virtual A *fn(); };
+struct B : virtual A { virtual B *fn(); };
+struct X : virtual B {};
+struct Y : virtual B {};
+struct C : X, Y {};
+struct D : virtual B, virtual A, C {
+ D *fn();
+ D();
+};
+D::D() {}
+
+// VFTABLES-LABEL: VFTable for 'test3::A' in 'test3::B' in 'test3::X' in 'test3::C' in 'test3::D' (3 entries).
+// VFTABLES-NEXT: 0 | test3::D *test3::D::fn()
+// VFTABLES-NEXT: [return adjustment (to type 'struct test3::A *'): vbase #1, 0 non-virtual]
+// VFTABLES-NEXT: [this adjustment: vtordisp at -4, 0 non-virtual]
+// VFTABLES-NEXT: 1 | test3::D *test3::D::fn()
+// VFTABLES-NEXT: [return adjustment (to type 'struct test3::B *'): vbase #2, 0 non-virtual]
+// VFTABLES-NEXT: [this adjustment: vtordisp at -4, 0 non-virtual]
+// VFTABLES-NEXT: 2 | test3::D *test3::D::fn()
+// VFTABLES-NEXT: [return adjustment (to type 'struct test3::D *'): 0 non-virtual]
+// VFTABLES-NEXT: [this adjustment: vtordisp at -4, 0 non-virtual]
+
+// GLOBALS-LABEL: @"??_7D@test3@@6B@" = {{.*}} constant { [3 x i8*] }
+// GLOBALS: @"?fn@D@test3@@$4PPPPPPPM@A@AEPAUA@2@XZ"
+// GLOBALS: @"?fn@D@test3@@$4PPPPPPPM@A@AEPAUB@2@XZ"
+// GLOBALS: @"?fn@D@test3@@$4PPPPPPPM@A@AEPAU12@XZ"
+}
+
+namespace pr34302 {
+// C::f is lives in the vftable inside its virtual B subobject. In the MS ABI,
+// covariant return type virtual methods extend vftables from virtual bases,
+// even though that can make it impossible to implement certain diamond
+// hierarchies correctly.
+struct A { virtual ~A(); };
+struct B : A { virtual B *f(); };
+struct C : virtual B { C *f(); };
+C c;
+// VFTABLES-LABEL: VFTable indices for 'pr34302::C' (2 entries).
+// VFTABLES-NEXT: -- accessible via vbtable index 1, vfptr at offset 0 --
+// VFTABLES-NEXT: 0 | pr34302::C::~C() [scalar deleting]
+// VFTABLES-NEXT: 2 | pr34302::C *pr34302::C::f()
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp
new file mode 100644
index 0000000..f84ffd5
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp
@@ -0,0 +1,316 @@
+// RUN: %clang_cc1 %s -fno-rtti -triple=i386-pc-win32 -emit-llvm -fdump-vtable-layouts -o %t.ll > %t
+// RUN: FileCheck --check-prefix=EMITS-VFTABLE %s < %t.ll
+// RUN: FileCheck --check-prefix=NO-VFTABLE %s < %t.ll
+// RUN: FileCheck %s < %t
+
+struct A {
+ // CHECK-LABEL: VFTable for 'A' (3 entries)
+ // CHECK-NEXT: 0 | void A::f()
+ // CHECK-NEXT: 1 | void A::g()
+ // CHECK-NEXT: 2 | void A::h()
+ // CHECK-LABEL: VFTable indices for 'A' (3 entries)
+ // CHECK-NEXT: 0 | void A::f()
+ // CHECK-NEXT: 1 | void A::g()
+ // CHECK-NEXT: 2 | void A::h()
+
+ virtual void f();
+ virtual void g();
+ virtual void h();
+ int ia;
+};
+A a;
+// EMITS-VFTABLE-DAG: @"??_7A@@6B@" = linkonce_odr unnamed_addr constant { [3 x i8*] }
+void use(A *obj) { obj->f(); }
+
+struct B : A {
+ // CHECK-LABEL: VFTable for 'A' in 'B' (5 entries)
+ // CHECK-NEXT: 0 | void B::f()
+ // CHECK-NEXT: 1 | void A::g()
+ // CHECK-NEXT: 2 | void A::h()
+ // CHECK-NEXT: 3 | void B::i()
+ // CHECK-NEXT: 4 | void B::j()
+ // CHECK-LABEL: VFTable indices for 'B' (3 entries)
+ // CHECK-NEXT: 0 | void B::f()
+ // CHECK-NEXT: 3 | void B::i()
+ // CHECK-NEXT: 4 | void B::j()
+
+ virtual void f(); // overrides A::f()
+ virtual void i();
+ virtual void j();
+};
+B b;
+// EMITS-VFTABLE-DAG: @"??_7B@@6B@" = linkonce_odr unnamed_addr constant { [5 x i8*] }
+void use(B *obj) { obj->f(); }
+
+struct C {
+ // CHECK-LABEL: VFTable for 'C' (2 entries)
+ // CHECK-NEXT: 0 | C::~C() [scalar deleting]
+ // CHECK-NEXT: 1 | void C::f()
+ // CHECK-LABEL: VFTable indices for 'C' (2 entries).
+ // CHECK-NEXT: 0 | C::~C() [scalar deleting]
+ // CHECK-NEXT: 1 | void C::f()
+
+ virtual ~C();
+ virtual void f();
+};
+void C::f() {}
+// NO-VFTABLE-NOT: @"??_7C@@6B@"
+void use(C *obj) { obj->f(); }
+
+struct D {
+ // CHECK-LABEL: VFTable for 'D' (2 entries)
+ // CHECK-NEXT: 0 | void D::f()
+ // CHECK-NEXT: 1 | D::~D() [scalar deleting]
+ // CHECK-LABEL: VFTable indices for 'D' (2 entries)
+ // CHECK-NEXT: 0 | void D::f()
+ // CHECK-NEXT: 1 | D::~D() [scalar deleting]
+
+ virtual void f();
+ virtual ~D();
+};
+D d;
+// EMITS-VFTABLE-DAG: @"??_7D@@6B@" = linkonce_odr unnamed_addr constant { [2 x i8*] }
+void use(D *obj) { obj->f(); }
+
+struct E : A {
+ // CHECK-LABEL: VFTable for 'A' in 'E' (5 entries)
+ // CHECK-NEXT: 0 | void A::f()
+ // CHECK-NEXT: 1 | void A::g()
+ // CHECK-NEXT: 2 | void A::h()
+ // CHECK-NEXT: 3 | E::~E() [scalar deleting]
+ // CHECK-NEXT: 4 | void E::i()
+ // CHECK-LABEL: VFTable indices for 'E' (2 entries).
+ // CHECK-NEXT: 3 | E::~E() [scalar deleting]
+ // CHECK-NEXT: 4 | void E::i()
+
+ // ~E would be the key method, but it isn't used, and MS ABI has no key
+ // methods.
+ virtual ~E();
+ virtual void i();
+};
+void E::i() {}
+// NO-VFTABLE-NOT: @"??_7E@@6B@"
+void use(E *obj) { obj->i(); }
+
+struct F : A {
+ // CHECK-LABEL: VFTable for 'A' in 'F' (5 entries)
+ // CHECK-NEXT: 0 | void A::f()
+ // CHECK-NEXT: 1 | void A::g()
+ // CHECK-NEXT: 2 | void A::h()
+ // CHECK-NEXT: 3 | void F::i()
+ // CHECK-NEXT: 4 | F::~F() [scalar deleting]
+ // CHECK-LABEL: VFTable indices for 'F' (2 entries).
+ // CHECK-NEXT: 3 | void F::i()
+ // CHECK-NEXT: 4 | F::~F() [scalar deleting]
+
+ virtual void i();
+ virtual ~F();
+};
+F f;
+// EMITS-VFTABLE-DAG: @"??_7F@@6B@" = linkonce_odr unnamed_addr constant { [5 x i8*] }
+void use(F *obj) { obj->i(); }
+
+struct G : E {
+ // CHECK-LABEL: VFTable for 'A' in 'E' in 'G' (6 entries)
+ // CHECK-NEXT: 0 | void G::f()
+ // CHECK-NEXT: 1 | void A::g()
+ // CHECK-NEXT: 2 | void A::h()
+ // CHECK-NEXT: 3 | G::~G() [scalar deleting]
+ // CHECK-NEXT: 4 | void E::i()
+ // CHECK-NEXT: 5 | void G::j()
+ // CHECK-LABEL: VFTable indices for 'G' (3 entries).
+ // CHECK-NEXT: 0 | void G::f()
+ // CHECK-NEXT: 3 | G::~G() [scalar deleting]
+ // CHECK-NEXT: 5 | void G::j()
+
+ virtual void f(); // overrides A::f()
+ virtual ~G();
+ virtual void j();
+};
+void G::j() {}
+// NO-VFTABLE-NOT: @"??_7G@@6B@"
+void use(G *obj) { obj->j(); }
+
+// Test that the usual Itanium-style key method does not emit a vtable.
+struct H {
+ virtual void f();
+};
+void H::f() {}
+// NO-VFTABLE-NOT: @"??_7H@@6B@"
+
+struct Empty { };
+
+struct I : Empty {
+ // CHECK-LABEL: VFTable for 'I' (2 entries)
+ // CHECK-NEXT: 0 | void I::f()
+ // CHECK-NEXT: 1 | void I::g()
+ virtual void f();
+ virtual void g();
+};
+
+I i;
+void use(I *obj) { obj->f(); }
+
+struct J {
+ // CHECK-LABEL: VFTable for 'J' (6 entries)
+ // CHECK-NEXT: 0 | void J::foo(long)
+ // CHECK-NEXT: 1 | void J::foo(int)
+ // CHECK-NEXT: 2 | void J::foo(short)
+ // CHECK-NEXT: 3 | void J::bar(long)
+ // CHECK-NEXT: 4 | void J::bar(int)
+ // CHECK-NEXT: 5 | void J::bar(short)
+ virtual void foo(short);
+ virtual void bar(short);
+ virtual void foo(int);
+ virtual void bar(int);
+ virtual void foo(long);
+ virtual void bar(long);
+};
+
+J j;
+void use(J *obj) { obj->foo(42); }
+
+struct K : J {
+ // CHECK-LABEL: VFTable for 'J' in 'K' (9 entries)
+ // CHECK-NEXT: 0 | void J::foo(long)
+ // CHECK-NEXT: 1 | void J::foo(int)
+ // CHECK-NEXT: 2 | void J::foo(short)
+ // CHECK-NEXT: 3 | void J::bar(long)
+ // CHECK-NEXT: 4 | void J::bar(int)
+ // CHECK-NEXT: 5 | void J::bar(short)
+ // CHECK-NEXT: 6 | void K::bar(double)
+ // CHECK-NEXT: 7 | void K::bar(float)
+ // CHECK-NEXT: 8 | void K::foo(float)
+ virtual void bar(float);
+ virtual void foo(float);
+ virtual void bar(double);
+};
+
+K k;
+void use(K *obj) { obj->foo(42.0f); }
+
+struct L : J {
+ // CHECK-LABEL: VFTable for 'J' in 'L' (9 entries)
+ // CHECK-NEXT: 0 | void J::foo(long)
+ // CHECK-NEXT: 1 | void L::foo(int)
+ // CHECK-NEXT: 2 | void J::foo(short)
+ // CHECK-NEXT: 3 | void J::bar(long)
+ // CHECK-NEXT: 4 | void J::bar(int)
+ // CHECK-NEXT: 5 | void J::bar(short)
+ // CHECK-NEXT: 6 | void L::foo(float)
+ // CHECK-NEXT: 7 | void L::bar(double)
+ // CHECK-NEXT: 8 | void L::bar(float)
+
+ // This case is interesting. Since the J::foo(int) override is the first method in
+ // the class, foo(float) precedes the bar(double) and bar(float) in the vftable.
+ virtual void foo(int);
+ virtual void bar(float);
+ virtual void foo(float);
+ virtual void bar(double);
+};
+
+L l;
+void use(L *obj) { obj->foo(42.0f); }
+
+struct M : J {
+ // CHECK-LABEL: VFTable for 'J' in 'M' (11 entries)
+ // CHECK-NEXT: 0 | void J::foo(long)
+ // CHECK-NEXT: 1 | void M::foo(int)
+ // CHECK-NEXT: 2 | void J::foo(short)
+ // CHECK-NEXT: 3 | void J::bar(long)
+ // CHECK-NEXT: 4 | void J::bar(int)
+ // CHECK-NEXT: 5 | void J::bar(short)
+ // CHECK-NEXT: 6 | void M::foo(float)
+ // CHECK-NEXT: 7 | void M::spam(long)
+ // CHECK-NEXT: 8 | void M::spam(int)
+ // CHECK-NEXT: 9 | void M::bar(double)
+ // CHECK-NEXT: 10 | void M::bar(float)
+
+ virtual void foo(int);
+ virtual void spam(int);
+ virtual void bar(float);
+ virtual void bar(double);
+ virtual void foo(float);
+ virtual void spam(long);
+};
+
+M m;
+void use(M *obj) { obj->foo(42.0f); }
+
+struct N {
+ // CHECK-LABEL: VFTable for 'N' (4 entries)
+ // CHECK-NEXT: 0 | void N::operator+(int)
+ // CHECK-NEXT: 1 | void N::operator+(short)
+ // CHECK-NEXT: 2 | void N::operator*(int)
+ // CHECK-NEXT: 3 | void N::operator*(short)
+ virtual void operator+(short);
+ virtual void operator*(short);
+ virtual void operator+(int);
+ virtual void operator*(int);
+};
+
+N n;
+void use(N *obj) { obj->operator+(42); }
+
+struct O { virtual A *f(); };
+struct P : O { virtual B *f(); };
+P p;
+void use(O *obj) { obj->f(); }
+void use(P *obj) { obj->f(); }
+// CHECK-LABEL: VFTable for 'O' (1 entry)
+// CHECK-NEXT: 0 | A *O::f()
+
+// CHECK-LABEL: VFTable for 'O' in 'P' (1 entry)
+// CHECK-NEXT: 0 | B *P::f()
+
+struct Q {
+ // CHECK-LABEL: VFTable for 'Q' (2 entries)
+ // CHECK-NEXT: 0 | void Q::foo(int)
+ // CHECK-NEXT: 1 | void Q::bar(int)
+ void foo(short);
+ void bar(short);
+ virtual void bar(int);
+ virtual void foo(int);
+};
+
+Q q;
+void use(Q *obj) { obj->foo(42); }
+
+// Inherited non-virtual overloads don't participate in the ordering.
+struct R : Q {
+ // CHECK-LABEL: VFTable for 'Q' in 'R' (4 entries)
+ // CHECK-NEXT: 0 | void Q::foo(int)
+ // CHECK-NEXT: 1 | void Q::bar(int)
+ // CHECK-NEXT: 2 | void R::bar(long)
+ // CHECK-NEXT: 3 | void R::foo(long)
+ virtual void bar(long);
+ virtual void foo(long);
+};
+
+R r;
+void use(R *obj) { obj->foo(42l); }
+
+struct S {
+ // CHECK-LABEL: VFTable for 'S' (1 entry).
+ // CHECK-NEXT: 0 | void S::f() [deleted]
+ virtual void f() = delete;
+ S();
+ // EMITS-VFTABLE-DAG: @"??_7S@@6B@" = linkonce_odr unnamed_addr constant { [1 x i8*] } { [1 x i8*] [i8* bitcast (void ()* @_purecall to i8*)] }
+};
+
+S::S() {}
+
+struct T {
+ struct U {};
+};
+struct V : T {
+ // CHECK-LABEL: VFTable for 'V' (2 entries).
+ // CHECK-NEXT: 0 | void V::U()
+ // CHECK-NEXT: 1 | void V::f()
+ using T::U;
+ virtual void f();
+ virtual void U();
+ V();
+};
+
+V::V() {}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance-vtordisps.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance-vtordisps.cpp
new file mode 100644
index 0000000..c5ce69f
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance-vtordisps.cpp
@@ -0,0 +1,569 @@
+// RUN: %clang_cc1 -fno-rtti -emit-llvm -fdump-vtable-layouts %s -o %t.ll -triple=i386-pc-win32 > %t
+// RUN: FileCheck %s < %t
+// RUN: FileCheck --check-prefix=MANGLING %s < %t.ll
+
+// For now, just make sure x86_64 doesn't crash.
+// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -fdump-vtable-layouts %s -triple=x86_64-pc-win32 > /dev/null
+
+struct V1 {
+ virtual void f();
+ virtual ~V1();
+};
+
+struct V2 {
+ virtual void f();
+ virtual ~V2();
+ int v;
+};
+
+struct Z {
+ virtual void g();
+ virtual ~Z();
+ int x;
+};
+
+struct V3 : Z, V2 {
+};
+
+struct V4 : Z, V1, V2 {
+ int y;
+};
+
+void use_somewhere_else(void*);
+
+namespace simple {
+// In case of a single-layer virtual inheritance, the "this" adjustment for a
+// virtual method is done statically:
+// struct A {
+// virtual void f(); // Expects "(A*)this" in ECX
+// };
+// struct B : virtual A {
+// virtual void f(); // Expects "(char*)(B*)this + 12" in ECX
+// virtual ~B(); // Might call f()
+// };
+//
+// If a class overrides a virtual function of its base and has a non-trivial
+// ctor/dtor that call(s) the virtual function (or may escape "this" to some
+// code that might call it), a virtual adjustment might be needed in case the
+// current class layout and the most derived class layout are different.
+// This is done using vtordisp thunks.
+//
+// A simple vtordisp{x,y} thunk for Method@Class is something like:
+// sub ecx, [ecx+x] // apply the vtordisp adjustment
+// sub ecx, y // apply the subobject adjustment, if needed.
+// jmp Method@Class
+
+struct A : virtual V1 {
+ // CHECK-LABEL: VFTable for 'V1' in 'simple::A' (2 entries).
+ // CHECK-NEXT: 0 | void simple::A::f()
+ // CHECK-NEXT: [this adjustment: vtordisp at -4, 0 non-virtual]
+ // CHECK-NEXT: 1 | simple::A::~A() [scalar deleting]
+ // CHECK-NEXT: [this adjustment: vtordisp at -4, 0 non-virtual]
+
+ // CHECK-LABEL: Thunks for 'simple::A::~A()' (1 entry).
+ // CHECK-NEXT: 0 | [this adjustment: vtordisp at -4, 0 non-virtual]
+
+ // CHECK-LABEL: Thunks for 'void simple::A::f()' (1 entry).
+ // CHECK-NEXT: 0 | [this adjustment: vtordisp at -4, 0 non-virtual]
+
+ virtual void f();
+ // MANGLING-DAG: @"?f@A@simple@@$4PPPPPPPM@A@AEXXZ"
+
+ virtual ~A();
+ // MANGLING-DAG: @"??_EA@simple@@$4PPPPPPPM@A@AEPAXI@Z"
+};
+
+A a;
+void use(A *obj) { obj->f(); }
+
+struct B : virtual V3 {
+ // CHECK-LABEL: VFTable for 'Z' in 'V3' in 'simple::B' (2 entries).
+ // CHECK-NEXT: 0 | void Z::g()
+ // CHECK-NEXT: 1 | simple::B::~B() [scalar deleting]
+ // CHECK-NEXT: [this adjustment: vtordisp at -4, 0 non-virtual]
+
+ // CHECK-LABEL: Thunks for 'simple::B::~B()' (1 entry).
+ // CHECK-NEXT: 0 | [this adjustment: vtordisp at -4, 0 non-virtual]
+
+ // CHECK-LABEL: VFTable for 'V2' in 'V3' in 'simple::B' (2 entries).
+ // CHECK-NEXT: 0 | void simple::B::f()
+ // CHECK-NEXT: [this adjustment: vtordisp at -12, 0 non-virtual]
+ // CHECK-NEXT: 1 | simple::B::~B() [scalar deleting]
+ // CHECK-NEXT: [this adjustment: vtordisp at -12, -8 non-virtual]
+
+ // CHECK-LABEL: Thunks for 'simple::B::~B()' (1 entry).
+ // CHECK-NEXT: 0 | [this adjustment: vtordisp at -12, -8 non-virtual]
+
+ // CHECK-LABEL: Thunks for 'void simple::B::f()' (1 entry).
+ // CHECK-NEXT: 0 | [this adjustment: vtordisp at -12, 0 non-virtual]
+
+ // FIXME: The vtordisp thunk should only get emitted for a constructor
+ // if "this" leaves scope.
+ B() { use_somewhere_else(this); }
+
+ virtual void f();
+ // MANGLING-DAG: @"?f@B@simple@@$4PPPPPPPE@A@AEXXZ"
+
+ // Has an implicit destructor.
+ // MANGLING-DAG: @"??_EB@simple@@$4PPPPPPPE@7AEPAXI@Z"
+ // MANGLING-DAG: @"??_EB@simple@@$4PPPPPPPM@A@AEPAXI@Z"
+};
+
+B b;
+void use(B *obj) { obj->f(); }
+
+struct C : virtual V4 {
+ // CHECK-LABEL: VFTable for 'Z' in 'V4' in 'simple::C' (2 entries).
+ // CHECK-NEXT: 0 | void Z::g()
+ // CHECK-NEXT: 1 | simple::C::~C() [scalar deleting]
+ // CHECK-NEXT: [this adjustment: vtordisp at -4, 0 non-virtual]
+
+ // CHECK-LABEL: Thunks for 'simple::C::~C()' (1 entry).
+ // CHECK-NEXT: 0 | [this adjustment: vtordisp at -4, 0 non-virtual]
+
+ // CHECK-LABEL: VFTable for 'V1' in 'V4' in 'simple::C' (2 entries).
+ // CHECK-NEXT: 0 | void simple::C::f()
+ // CHECK-NEXT: [this adjustment: vtordisp at -12, 0 non-virtual]
+ // CHECK-NEXT: 1 | simple::C::~C() [scalar deleting]
+ // CHECK-NEXT: [this adjustment: vtordisp at -12, -8 non-virtual]
+
+ // CHECK-LABEL: Thunks for 'simple::C::~C()' (1 entry).
+ // CHECK-NEXT: 0 | [this adjustment: vtordisp at -12, -8 non-virtual]
+
+ // CHECK-LABEL: Thunks for 'void simple::C::f()' (1 entry).
+ // CHECK-NEXT: 0 | [this adjustment: vtordisp at -12, 0 non-virtual]
+
+ // CHECK-LABEL: VFTable for 'V2' in 'V4' in 'simple::C' (2 entries).
+ // CHECK-NEXT: 0 | void simple::C::f()
+ // CHECK-NEXT: [this adjustment: vtordisp at -16, -4 non-virtual]
+ // CHECK-NEXT: 1 | simple::C::~C() [scalar deleting]
+ // CHECK-NEXT: [this adjustment: vtordisp at -16, -12 non-virtual]
+
+ // CHECK-LABEL: Thunks for 'simple::C::~C()' (1 entry).
+ // CHECK-NEXT: 0 | [this adjustment: vtordisp at -16, -12 non-virtual]
+
+ // CHECK-LABEL: Thunks for 'void simple::C::f()' (1 entry).
+ // CHECK-NEXT: 0 | [this adjustment: vtordisp at -16, -4 non-virtual]
+
+ int x;
+ virtual void f();
+ // MANGLING-DAG: @"?f@C@simple@@$4PPPPPPPA@3AEXXZ"
+ // MANGLING-DAG: @"?f@C@simple@@$4PPPPPPPE@A@AEXXZ"
+ virtual ~C();
+ // MANGLING-DAG: @"??_EC@simple@@$4PPPPPPPA@M@AEPAXI@Z"
+ // MANGLING-DAG: @"??_EC@simple@@$4PPPPPPPE@7AEPAXI@Z"
+ // MANGLING-DAG: @"??_EC@simple@@$4PPPPPPPM@A@AEPAXI@Z"
+};
+
+C c;
+void use(C *obj) { obj->f(); }
+
+class D : B {
+ // CHECK-LABEL: VFTable for 'V2' in 'V3' in 'simple::B' in 'simple::D' (2 entries).
+ // CHECK-NEXT: 0 | void simple::B::f()
+ // CHECK-NEXT: [this adjustment: vtordisp at -12, -4 non-virtual]
+ // CHECK-NEXT: 1 | simple::D::~D() [scalar deleting]
+ // CHECK-NEXT: [this adjustment: vtordisp at -12, -8 non-virtual]
+ D();
+ int z;
+
+ // MANGLING-DAG: @"?f@B@simple@@$4PPPPPPPE@3AEXXZ"
+};
+
+D::D() {}
+
+struct E : V3 {
+ virtual void f();
+};
+
+struct F : virtual E {
+ // CHECK-LABEL: VFTable for 'Z' in 'V3' in 'simple::E' in 'simple::F' (2 entries).
+ // CHECK-NEXT: 0 | void simple::F::g()
+ // CHECK-NEXT: [this adjustment: vtordisp at -4, 0 non-virtual]
+ // CHECK-NEXT: 1 | simple::F::~F() [scalar deleting]
+ // CHECK-NEXT: [this adjustment: vtordisp at -4, 0 non-virtual]
+
+ // CHECK-LABEL: VFTable for 'V2' in 'V3' in 'simple::E' in 'simple::F' (2 entries).
+ // CHECK-NEXT: 0 | void simple::E::f()
+ // CHECK-NEXT: 1 | simple::F::~F() [scalar deleting]
+ // CHECK-NEXT: [this adjustment: vtordisp at -12, -8 non-virtual]
+
+ F();
+ virtual void g(); // Force a vtordisp.
+ int f;
+
+ // MANGLING-DAG: @"?g@F@simple@@$4PPPPPPPM@A@AEXXZ"{{.*}}??_EF@simple@@$4PPPPPPPM@A@AEPAXI@Z
+ // MANGLING-DAG: ?f@E@simple@@UAEXXZ{{.*}}??_EF@simple@@$4PPPPPPPE@7AEPAXI@Z
+};
+
+F::F() {}
+
+struct G : F {
+ // CHECK-LABEL: VFTable for 'Z' in 'V3' in 'simple::E' in 'simple::F' in 'simple::G' (2 entries).
+ // CHECK-NEXT: 0 | void simple::F::g()
+ // CHECK-NEXT: [this adjustment: vtordisp at -4, -4 non-virtual]
+ // CHECK-NEXT: 1 | simple::G::~G() [scalar deleting]
+ // CHECK-NEXT: [this adjustment: vtordisp at -4, 0 non-virtual]
+
+ // CHECK-LABEL: VFTable for 'V2' in 'V3' in 'simple::E' in 'simple::F' in 'simple::G' (2 entries).
+ // CHECK-NEXT: 0 | void simple::E::f()
+ // CHECK-NEXT: 1 | simple::G::~G() [scalar deleting]
+ // CHECK-NEXT: [this adjustment: vtordisp at -12, -8 non-virtual]
+
+ G();
+ int g;
+
+ // MANGLING-DAG: @"?g@F@simple@@$4PPPPPPPM@3AEXXZ"{{.*}}@"??_EG@simple@@$4PPPPPPPM@A@AEPAXI@Z"
+ // MANGLING-DAG: @"?f@E@simple@@UAEXXZ"{{.*}}@"??_EG@simple@@$4PPPPPPPE@7AEPAXI@Z"
+};
+
+G::G() {}
+}
+
+namespace extended {
+// If a virtual function requires vtordisp adjustment and the final overrider
+// is defined in another virtual base of the most derived class,
+// we need to know two vbase offsets.
+// In this case, we should use the extended form of vtordisp thunks, called
+// vtordispex thunks.
+//
+// vtordispex{x,y,z,w} thunk for Method@Class is something like:
+// sub ecx, [ecx+z] // apply the vtordisp adjustment
+// sub ecx, x // jump to the vbptr of the most derived class
+// mov eax, [ecx] // load the vbtable address
+// add ecx, [eax+y] // lookup the final overrider's vbase offset
+// add ecx, w // apphy the subobject offset if needed
+// jmp Method@Class
+
+struct A : virtual simple::A {
+ // CHECK-LABEL: VFTable for 'V1' in 'simple::A' in 'extended::A' (2 entries).
+ // CHECK-NEXT: 0 | void simple::A::f()
+ // CHECK-NEXT: [this adjustment: vtordisp at -4, vbptr at 8 to the left,
+ // CHECK-NEXT: vboffset at 8 in the vbtable, 8 non-virtual]
+ // CHECK-NEXT: 1 | extended::A::~A() [scalar deleting]
+ // CHECK-NEXT: [this adjustment: vtordisp at -4, 0 non-virtual]
+
+ // CHECK-LABEL: Thunks for 'void simple::A::f()' (1 entry).
+ // CHECK-NEXT: 0 | [this adjustment: vtordisp at -4, vbptr at 8 to the left,
+ // CHECK-NEXT: vboffset at 8 in the vbtable, 8 non-virtual]
+
+ // `vtordispex{8,8,4294967292,8}'
+ // MANGLING-DAG: @"?f@A@simple@@$R477PPPPPPPM@7AEXXZ"
+
+ virtual ~A();
+ // vtordisp{4294967292,0}
+ // MANGLING-DAG: @"??_EA@extended@@$4PPPPPPPM@A@AEPAXI@Z"
+};
+
+A a;
+void use(A *obj) { delete obj; }
+
+struct B : virtual simple::A {
+ // This class has an implicit dtor. Vdtors don't require vtordispex thunks
+ // as the most derived class always has an implicit dtor,
+ // which is a final overrider.
+
+ // CHECK-LABEL: VFTable for 'V1' in 'simple::A' in 'extended::B' (2 entries).
+ // ...
+ // CHECK: 1 | extended::B::~B() [scalar deleting]
+ // CHECK-NEXT: [this adjustment: vtordisp at -4, 0 non-virtual]
+
+ // CHECK-LABEL: Thunks for 'void simple::A::f()' (1 entry).
+ // CHECK-NEXT: 0 | [this adjustment: vtordisp at -4, vbptr at 8 to the left,
+ // CHECK-NEXT: vboffset at 8 in the vbtable, 8 non-virtual]
+
+ // vtordisp{4294967292,0}
+ // MANGLING-DAG: @"??_EB@extended@@$4PPPPPPPM@A@AEPAXI@Z"
+};
+
+B b;
+void use(B *obj) { delete obj; }
+
+struct C : virtual simple::A {
+ // CHECK-LABEL: VFTable for 'V1' in 'simple::A' in 'extended::C' (2 entries).
+ // CHECK-NEXT: 0 | void simple::A::f()
+ // CHECK-NEXT: [this adjustment: vtordisp at -4, vbptr at 12 to the left,
+ // CHECK-NEXT: vboffset at 8 in the vbtable, 8 non-virtual]
+
+ // CHECK-LABEL: Thunks for 'void simple::A::f()' (1 entry).
+ // CHECK-NEXT: 0 | [this adjustment: vtordisp at -4, vbptr at 12 to the left,
+ // CHECK-NEXT: vboffset at 8 in the vbtable, 8 non-virtual]
+
+ // `vtordispex{12,8,4294967292,8}'
+ // MANGLING-DAG: @"?f@A@simple@@$R4M@7PPPPPPPM@7AEXXZ"
+ int x;
+ virtual ~C();
+ // MANGLING-DAG: @"??_EC@extended@@$4PPPPPPPM@A@AEPAXI@Z"
+};
+
+C c;
+void use(C *obj) { delete obj; }
+
+struct D : virtual V2 {
+ virtual void f();
+ virtual ~D();
+ int x;
+};
+
+struct E : virtual D {
+ // CHECK-LABEL: VFTable for 'V2' in 'extended::D' in 'extended::E' (2 entries).
+ // CHECK-NEXT: 0 | void extended::D::f()
+ // CHECK-NEXT: [this adjustment: vtordisp at -4, vbptr at 8 to the left,
+ // CHECK-NEXT: vboffset at 8 in the vbtable, 12 non-virtual]
+
+ // CHECK-LABEL: Thunks for 'void extended::D::f()' (1 entry).
+ // CHECK-NEXT: 0 | [this adjustment: vtordisp at -4, vbptr at 8 to the left,
+ // CHECK-NEXT: vboffset at 8 in the vbtable, 12 non-virtual]
+
+ // `vtordispex{8,8,4294967292,12}'
+ // MANGLING-DAG: @"?f@D@extended@@$R477PPPPPPPM@M@AEXXZ"
+
+ virtual ~E();
+ // MANGLING-DAG: @"??_EE@extended@@$4PPPPPPPM@A@AEPAXI@Z"
+};
+
+E e;
+void use(E *obj) { delete obj; }
+
+struct F : virtual Z, virtual D {
+ // CHECK-LABEL: VFTable for 'V2' in 'extended::D' in 'extended::F' (2 entries).
+ // CHECK-NEXT: 0 | void extended::D::f()
+ // CHECK-NEXT: [this adjustment: vtordisp at -4, vbptr at 20 to the left,
+ // CHECK-NEXT: vboffset at 12 in the vbtable, 12 non-virtual]
+
+ // CHECK-LABEL: Thunks for 'void extended::D::f()' (1 entry).
+ // CHECK-NEXT: 0 | [this adjustment: vtordisp at -4, vbptr at 20 to the left,
+ // CHECK-NEXT: vboffset at 12 in the vbtable, 12 non-virtual]
+
+ // `vtordispex{20,12,4294967292,12}'
+ // MANGLING-DAG: @"?f@D@extended@@$R4BE@M@PPPPPPPM@M@AEXXZ"
+ int x;
+ virtual ~F();
+ // MANGLING-DAG: @"??_EF@extended@@$4PPPPPPPM@M@AEPAXI@Z"
+};
+
+F f;
+void use(F *obj) { delete obj; }
+
+struct G : virtual simple::A {
+ // CHECK-LABEL: VFTable for 'extended::G' (1 entry).
+ // CHECK-NEXT: 0 | void extended::G::g()
+
+ // CHECK-LABEL: VFTable for 'V1' in 'simple::A' in 'extended::G' (2 entries).
+ // CHECK-NEXT: 0 | void simple::A::f()
+ // CHECK-NEXT: [this adjustment: vtordisp at -4, vbptr at 8 to the left,
+ // CHECK-NEXT: vboffset at 8 in the vbtable, 8 non-virtual]
+ // CHECK-NEXT: 1 | extended::G::~G() [scalar deleting]
+ // CHECK-NEXT: [this adjustment: vtordisp at -4, 0 non-virtual]
+
+ // CHECK-LABEL: Thunks for 'void simple::A::f()' (1 entry).
+ // CHECK-NEXT: 0 | [this adjustment: vtordisp at -4, vbptr at 8 to the left,
+ // CHECK-NEXT: vboffset at 8 in the vbtable, 8 non-virtual]
+
+ // Emits a G's own vfptr, thus moving the vbptr in the layout.
+ virtual void g();
+
+ virtual ~G();
+ // vtordisp{4294967292,0}
+ // MANGLING-DAG: @"??_EG@extended@@$4PPPPPPPM@A@AEPAXI@Z"
+};
+
+G g;
+void use(G *obj) { obj->g(); }
+
+struct H : Z, A {
+ // CHECK-LABEL: VFTable for 'Z' in 'extended::H' (2 entries).
+ // CHECK-NEXT: 0 | void Z::g()
+ // CHECK-NEXT: 1 | extended::H::~H() [scalar deleting]
+
+ // CHECK-LABEL: VFTable for 'V1' in 'simple::A' in 'extended::A' in 'extended::H' (2 entries).
+ // CHECK-NEXT: 0 | void simple::A::f()
+ // CHECK-NEXT: [this adjustment: vtordisp at -4, vbptr at 8 to the left,
+ // CHECK-NEXT: vboffset at 8 in the vbtable, 8 non-virtual]
+
+ // CHECK-LABEL: Thunks for 'void simple::A::f()' (1 entry).
+ // CHECK-NEXT: 0 | [this adjustment: vtordisp at -4, vbptr at 8 to the left,
+ // CHECK-NEXT: vboffset at 8 in the vbtable, 8 non-virtual]
+
+ // MANGLING-DAG: @"?f@A@simple@@$R477PPPPPPPM@7AEXXZ"
+ // MANGLING-DAG: @"??_EH@extended@@$4PPPPPPPM@BA@AEPAXI@Z"
+};
+
+H h;
+void use(H *obj) { delete obj; }
+}
+
+namespace pr17738 {
+// These classes should have vtordispex thunks but MSVS CL miscompiles them.
+// Just do the right thing.
+
+struct A : virtual simple::B {
+ // CHECK-LABEL: VFTable for 'V2' in 'V3' in 'simple::B' in 'pr17738::A' (2 entries).
+ // CHECK-NEXT: 0 | void simple::B::f()
+ // CHECK-NEXT: [this adjustment: vtordisp at -12, vbptr at 20 to the left,
+ // CHECK-NEXT: vboffset at 8 in the vbtable, 16 non-virtual]
+
+ // CHECK-LABEL: Thunks for 'void simple::B::f()' (1 entry).
+ // CHECK-NEXT: 0 | [this adjustment: vtordisp at -12, vbptr at 20 to the left,
+ // CHECK-NEXT: vboffset at 8 in the vbtable, 16 non-virtual]
+
+ // MANGLING-DAG: @"?f@B@simple@@$R4BE@7PPPPPPPE@BA@AEXXZ"
+ int a;
+ virtual ~A();
+};
+
+A a;
+void use(A *obj) { delete obj; }
+}
+
+namespace pr19408 {
+// In this test, the vptr used to vcall D::f() is located in the A vbase.
+// The offset of A in different in C and D, so the D vtordisp thunk should
+// adjust "this" so C::f gets the right value.
+struct A {
+ A();
+ virtual void f();
+ int a;
+};
+
+struct B : virtual A {
+ B();
+ int b;
+};
+
+struct C : B {
+ C();
+ virtual void f();
+ int c;
+};
+
+struct D : C {
+ // CHECK-LABEL: VFTable for 'pr19408::A' in 'pr19408::B' in 'pr19408::C' in 'pr19408::D' (1 entry).
+ // CHECK-NEXT: 0 | void pr19408::C::f()
+ // CHECK-NEXT: [this adjustment: vtordisp at -4, -4 non-virtual]
+
+ // MANGLING-DAG: @"?f@C@pr19408@@$4PPPPPPPM@3AEXXZ"
+ D();
+ int d;
+};
+
+D::D() {}
+}
+
+namespace access {
+struct A {
+ virtual ~A();
+protected:
+ virtual void prot();
+private:
+ virtual void priv();
+};
+
+struct B : virtual A {
+ virtual ~B();
+protected:
+ virtual void prot();
+ // MANGLING-DAG: @"?prot@B@access@@$2PPPPPPPM@A@AEXXZ"
+private:
+ virtual void priv();
+ // MANGLING-DAG: @"?priv@B@access@@$0PPPPPPPM@A@AEXXZ"
+};
+
+B b;
+
+struct C : virtual B {
+ virtual ~C();
+
+ // MANGLING-DAG: @"?prot@B@access@@$R277PPPPPPPM@7AEXXZ"
+ // MANGLING-DAG: @"?priv@B@access@@$R077PPPPPPPM@7AEXXZ"
+};
+
+C c;
+}
+
+namespace pr19505 {
+struct A {
+ virtual void f();
+ virtual void z();
+};
+
+struct B : A {
+ virtual void f();
+};
+
+struct C : A, B {
+ virtual void g();
+};
+
+struct X : B, virtual C {
+ X() {}
+ virtual void g();
+
+ // CHECK-LABEL: VFTable for 'pr19505::A' in 'pr19505::B' in 'pr19505::C' in 'pr19505::X' (2 entries).
+ // CHECK-NEXT: 0 | void pr19505::B::f()
+ // CHECK-NEXT: 1 | void pr19505::A::z()
+
+ // MANGLING-DAG: @"??_7X@pr19505@@6BB@1@@" = {{.*}}@"?f@B@pr19505@@UAEXXZ"
+} x;
+
+void build_vftable(X *obj) { obj->g(); }
+}
+
+namespace pr19506 {
+struct A {
+ virtual void f();
+ virtual void g();
+};
+
+struct B : A {
+ virtual void f();
+};
+
+struct C : B {};
+
+struct X : C, virtual B {
+ virtual void g();
+ X() {}
+
+ // CHECK-LABEL: VFTable for 'pr19506::A' in 'pr19506::B' in 'pr19506::X' (2 entries).
+ // CHECK-NEXT: 0 | void pr19506::B::f()
+ // CHECK-NEXT: 1 | void pr19506::X::g()
+ // CHECK-NEXT: [this adjustment: vtordisp at -4, -12 non-virtual]
+
+ // MANGLING-DAG: @"??_7X@pr19506@@6BB@1@@" = {{.*}}@"?f@B@pr19506@@UAEXXZ"
+} x;
+
+void build_vftable(X *obj) { obj->g(); }
+}
+
+namespace pr19519 {
+// VS2013 CL miscompiles this, just make sure we don't regress.
+
+struct A {
+ virtual void f();
+ virtual void g();
+};
+
+struct B : virtual A {
+ virtual void f();
+ B();
+};
+
+struct C : virtual A {
+ virtual void g();
+};
+
+struct X : B, C {
+ X();
+
+ // CHECK-LABEL: VFTable for 'pr19519::A' in 'pr19519::B' in 'pr19519::X' (2 entries).
+ // CHECK-NEXT: 0 | void pr19519::B::f()
+ // CHECK-NEXT: [this adjustment: vtordisp at -4, -4 non-virtual]
+ // CHECK-NEXT: 1 | void pr19519::C::g()
+ // CHECK-NEXT: [this adjustment: vtordisp at -4, -4 non-virtual]
+
+ // MANGLING-DAG: @"??_7X@pr19519@@6B@" = {{.*}}@"?g@C@pr19519@@$4PPPPPPPM@3AEXXZ"
+};
+
+X::X() {}
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp
new file mode 100644
index 0000000..8e309ac
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp
@@ -0,0 +1,847 @@
+// RUN: %clang_cc1 -std=c++11 -fms-extensions -fno-rtti -emit-llvm -o %t.ll -fdump-vtable-layouts %s -triple=i386-pc-win32 >%t
+// RUN: FileCheck %s < %t
+// RUN: FileCheck --check-prefix=MANGLING %s < %t.ll
+
+struct Empty { };
+
+struct A {
+ virtual void f();
+ virtual void z(); // Useful to check there are no thunks for f() when appropriate.
+};
+
+struct B {
+ virtual void g();
+};
+
+struct C: virtual A {
+ // CHECK-LABEL: VFTable for 'A' in 'C' (2 entries)
+ // CHECK-NEXT: 0 | void C::f()
+ // CHECK-NEXT: 1 | void A::z()
+
+ // CHECK-LABEL: VFTable indices for 'C' (1 entry)
+ // CHECK-NEXT: vbtable index 1, vfptr at offset 0
+ // CHECK-NEXT: 0 | void C::f()
+
+ // MANGLING-DAG: @"??_7C@@6B@"
+
+ virtual void f() {}
+};
+
+C c;
+void use(C *obj) { obj->f(); }
+
+struct D: virtual A {
+ // CHECK-LABEL: VFTable for 'D' (1 entry).
+ // CHECK-NEXT: 0 | void D::h()
+
+ // CHECK-LABEL: VFTable for 'A' in 'D' (2 entries).
+ // CHECK-NEXT: 0 | void D::f()
+ // CHECK-NEXT: 1 | void A::z()
+
+ // CHECK-LABEL: VFTable indices for 'D' (2 entries).
+ // CHECK-NEXT: via vfptr at offset 0
+ // CHECK-NEXT: 0 | void D::h()
+ // CHECK-NEXT: via vbtable index 1, vfptr at offset 0
+ // CHECK-NEXT: 0 | void D::f()
+
+ // MANGLING-DAG: @"??_7D@@6B0@@"
+ // MANGLING-DAG: @"??_7D@@6BA@@@"
+
+ virtual void f();
+ virtual void h();
+};
+
+D d;
+void use(D *obj) { obj->h(); }
+
+namespace Test1 {
+
+struct X { int x; };
+
+// X and A get reordered in the layout since X doesn't have a vfptr while A has.
+struct Y : X, A { };
+// MANGLING-DAG: @"??_7Y@Test1@@6B@"
+
+struct Z : virtual Y {
+ Z();
+ // CHECK-LABEL: VFTable for 'A' in 'Test1::Y' in 'Test1::Z' (2 entries).
+ // CHECK-NEXT: 0 | void A::f()
+ // CHECK-NEXT: 1 | void A::z()
+
+ // CHECK-NOT: VFTable indices for 'Test1::Z'
+
+ // MANGLING-DAG: @"??_7Z@Test1@@6B@"
+};
+
+Z::Z() {}
+}
+
+namespace Test2 {
+
+struct X: virtual A, virtual B {
+ // CHECK-LABEL: VFTable for 'Test2::X' (1 entry).
+ // CHECK-NEXT: 0 | void Test2::X::h()
+
+ // CHECK-LABEL: VFTable for 'A' in 'Test2::X' (2 entries).
+ // CHECK-NEXT: 0 | void A::f()
+ // CHECK-NEXT: 1 | void A::z()
+
+ // CHECK-LABEL: VFTable for 'B' in 'Test2::X' (1 entry).
+ // CHECK-NEXT: 0 | void B::g()
+
+ // CHECK-LABEL: VFTable indices for 'Test2::X' (1 entry).
+ // CHECK-NEXT: 0 | void Test2::X::h()
+
+ // MANGLING-DAG: @"??_7X@Test2@@6B01@@"
+ // MANGLING-DAG: @"??_7X@Test2@@6BA@@@"
+ // MANGLING-DAG: @"??_7X@Test2@@6BB@@@"
+
+ virtual void h();
+};
+
+X x;
+void use(X *obj) { obj->h(); }
+}
+
+namespace Test3 {
+
+struct X : virtual A {
+ // MANGLING-DAG: @"??_7X@Test3@@6B@"
+};
+
+struct Y: virtual X {
+ Y();
+ // CHECK-LABEL: VFTable for 'A' in 'Test3::X' in 'Test3::Y' (2 entries).
+ // CHECK-NEXT: 0 | void A::f()
+ // CHECK-NEXT: 1 | void A::z()
+
+ // CHECK-NOT: VFTable indices for 'Test3::Y'
+
+ // MANGLING-DAG: @"??_7Y@Test3@@6B@"
+};
+
+Y::Y() {}
+}
+
+namespace Test4 {
+
+struct X: virtual C {
+ X();
+ // This one's interesting. C::f expects (A*) to be passed as 'this' and does
+ // ECX-=4 to cast to (C*). In X, C and A vbases are reordered, so the thunk
+ // should pass a pointer to the end of X in order
+ // for ECX-=4 to point at the C part.
+
+ // CHECK-LABEL: VFTable for 'A' in 'C' in 'Test4::X' (2 entries).
+ // CHECK-NEXT: 0 | void C::f()
+ // CHECK-NEXT: [this adjustment: 8 non-virtual]
+ // CHECK-NEXT: 1 | void A::z()
+
+ // CHECK-LABEL: Thunks for 'void C::f()' (1 entry).
+ // CHECK-NEXT: 0 | [this adjustment: 8 non-virtual]
+
+ // CHECK-NOT: VFTable indices for 'Test4::X'
+
+ // MANGLING-DAG: @"??_7X@Test4@@6B@"
+
+ // Also check the mangling of the thunk.
+ // MANGLING-DAG: define linkonce_odr dso_local x86_thiscallcc void @"?f@C@@WPPPPPPPI@AEXXZ"
+};
+
+X::X() {}
+}
+
+namespace Test5 {
+
+// New methods are added to the base's vftable.
+struct X : A {
+ // MANGLING-DAG: @"??_7X@Test5@@6B@"
+ virtual void g();
+};
+
+struct Y : virtual X {
+ // CHECK-LABEL: VFTable for 'Test5::Y' (1 entry).
+ // CHECK-NEXT: 0 | void Test5::Y::h()
+
+ // CHECK-LABEL: VFTable for 'A' in 'Test5::X' in 'Test5::Y' (3 entries).
+ // CHECK-NEXT: 0 | void A::f()
+ // CHECK-NEXT: 1 | void A::z()
+ // CHECK-NEXT: 2 | void Test5::X::g()
+
+ // CHECK-LABEL: VFTable indices for 'Test5::Y' (1 entry).
+ // CHECK-NEXT: 0 | void Test5::Y::h()
+
+ // MANGLING-DAG: @"??_7Y@Test5@@6B01@@"
+ // MANGLING-DAG: @"??_7Y@Test5@@6BX@1@@"
+
+ virtual void h();
+};
+
+Y y;
+void use(Y *obj) { obj->h(); }
+}
+
+namespace Test6 {
+
+struct X : A, virtual Empty {
+ X();
+ // CHECK-LABEL: VFTable for 'A' in 'Test6::X' (2 entries).
+ // CHECK-NEXT: 0 | void A::f()
+ // CHECK-NEXT: 1 | void A::z()
+
+ // CHECK-NOT: VFTable indices for 'Test6::X'
+
+ // MANGLING-DAG: @"??_7X@Test6@@6B@"
+};
+
+X::X() {}
+}
+
+namespace Test7 {
+
+struct X : C {
+ // MANGLING-DAG: @"??_7X@Test7@@6B@"
+};
+
+struct Y : virtual X {
+ Y();
+ // CHECK-LABEL: VFTable for 'A' in 'C' in 'Test7::X' in 'Test7::Y' (2 entries).
+ // CHECK-NEXT: 0 | void C::f()
+ // CHECK-NEXT: [this adjustment: 8 non-virtual]
+ // CHECK-NEXT: 1 | void A::z()
+
+ // CHECK-LABEL: Thunks for 'void C::f()' (1 entry).
+ // CHECK-NEXT: 0 | [this adjustment: 8 non-virtual]
+
+ // CHECK-NOT: VFTable indices for 'Test7::Y'
+
+ // MANGLING-DAG: @"??_7Y@Test7@@6B@"
+};
+
+Y::Y() {}
+}
+
+namespace Test8 {
+
+// This is a typical diamond inheritance with a shared 'A' vbase.
+struct X : D, C {
+ // CHECK-LABEL: VFTable for 'D' in 'Test8::X' (1 entry).
+ // CHECK-NEXT: 0 | void D::h()
+
+ // CHECK-LABEL: VFTable for 'A' in 'D' in 'Test8::X' (2 entries).
+ // CHECK-NEXT: 0 | void Test8::X::f()
+ // CHECK-NEXT: 1 | void A::z()
+
+ // CHECK-LABEL: VFTable indices for 'Test8::X' (1 entry).
+ // CHECK-NEXT: via vbtable index 1, vfptr at offset 0
+ // CHECK-NEXT: 0 | void Test8::X::f()
+
+ // MANGLING-DAG: @"??_7X@Test8@@6BA@@@"
+ // MANGLING-DAG: @"??_7X@Test8@@6BD@@@"
+
+ virtual void f();
+};
+
+X x;
+void use(X *obj) { obj->f(); }
+
+// Another diamond inheritance which led to AST crashes.
+struct Y : virtual A {};
+
+struct Z : Y, C {
+ // CHECK-LABEL: VFTable for 'A' in 'Test8::Y' in 'Test8::Z' (2 entries).
+ // CHECK-NEXT: 0 | void Test8::Z::f()
+ // CHECK-NEXT: 1 | void A::z()
+
+ // CHECK-LABEL: VFTable indices for 'Test8::Z' (1 entry).
+ // CHECK-NEXT: via vbtable index 1, vfptr at offset 0
+ // CHECK-NEXT: 0 | void Test8::Z::f()
+ virtual void f();
+};
+Z z;
+void use(Z *obj) { obj->f(); }
+
+// Another diamond inheritance which we miscompiled (PR18967).
+struct W : virtual A {
+ virtual void bar();
+};
+
+struct T : W, C {
+ // CHECK-LABEL: VFTable for 'Test8::W' in 'Test8::T' (1 entry)
+ // CHECK-NEXT: 0 | void Test8::T::bar()
+
+ // CHECK-LABEL: VFTable for 'A' in 'Test8::W' in 'Test8::T' (2 entries)
+ // CHECK-NEXT: 0 | void C::f()
+ // CHECK-NEXT: [this adjustment: -4 non-virtual]
+ // CHECK-NEXT: 1 | void A::z()
+
+ // CHECK-LABEL: Thunks for 'void C::f()' (1 entry).
+ // CHECK-NEXT: 0 | [this adjustment: -4 non-virtual]
+ virtual void bar();
+ int field;
+};
+T t;
+void use(T *obj) { obj->bar(); }
+}
+
+namespace Test9 {
+
+struct X : A { };
+
+struct Y : virtual X {
+ // CHECK-LABEL: VFTable for 'Test9::Y' (1 entry).
+ // CHECK-NEXT: 0 | void Test9::Y::h()
+
+ // CHECK-LABEL: VFTable for 'A' in 'Test9::X' in 'Test9::Y' (2 entries).
+ // CHECK-NEXT: 0 | void A::f()
+ // CHECK-NEXT: 1 | void A::z()
+
+ // CHECK-LABEL: VFTable indices for 'Test9::Y' (1 entry).
+ // CHECK-NEXT: 0 | void Test9::Y::h()
+
+ // MANGLING-DAG: @"??_7Y@Test9@@6B01@@"
+ // MANGLING-DAG: @"??_7Y@Test9@@6BX@1@@"
+
+ virtual void h();
+};
+
+Y y;
+void use(Y *obj) { obj->h(); }
+
+struct Z : Y, virtual B {
+ Z();
+ // CHECK-LABEL: VFTable for 'Test9::Y' in 'Test9::Z' (1 entry).
+ // CHECK-NEXT: 0 | void Test9::Y::h()
+
+ // CHECK-LABEL: VFTable for 'A' in 'Test9::X' in 'Test9::Y' in 'Test9::Z' (2 entries).
+ // CHECK-NEXT: 0 | void A::f()
+ // CHECK-NEXT: 1 | void A::z()
+
+ // CHECK-LABEL: VFTable for 'B' in 'Test9::Z' (1 entry).
+ // CHECK-NEXT: 0 | void B::g()
+
+ // CHECK-NOT: VFTable indices for 'Test9::Z'
+
+ // MANGLING-DAG: @"??_7Z@Test9@@6BX@1@@"
+ // MANGLING-DAG: @"??_7Z@Test9@@6BY@1@@"
+
+ // MANGLING-DAG: @"??_7Z@Test9@@6B@"
+};
+
+Z::Z() {}
+
+struct W : Z, D, virtual A, virtual B {
+ W();
+ // CHECK-LABEL: VFTable for 'Test9::Y' in 'Test9::Z' in 'Test9::W' (1 entry).
+ // CHECK-NEXT: 0 | void Test9::Y::h()
+
+ // CHECK-LABEL: VFTable for 'A' in 'Test9::X' in 'Test9::Y' in 'Test9::Z' in 'Test9::W' (2 entries).
+ // CHECK-NEXT: 0 | void A::f()
+ // CHECK-NEXT: 1 | void A::z()
+
+ // CHECK-LABEL: VFTable for 'B' in 'Test9::Z' in 'Test9::W' (1 entry).
+ // CHECK-NEXT: 0 | void B::g()
+
+ // CHECK-LABEL: VFTable for 'D' in 'Test9::W' (1 entry).
+ // CHECK-NEXT: 0 | void D::h()
+
+ // CHECK-LABEL: VFTable for 'A' in 'D' in 'Test9::W' (2 entries).
+ // CHECK-NEXT: 0 | void D::f()
+ // CHECK-NEXT: [this adjustment: -8 non-virtual]
+ // CHECK-NEXT: 1 | void A::z()
+
+ // CHECK-LABEL: Thunks for 'void D::f()' (1 entry).
+ // CHECK-NEXT: 0 | [this adjustment: -8 non-virtual]
+
+ // CHECK-NOT: VFTable indices for 'Test9::W'
+
+ // MANGLING-DAG: @"??_7W@Test9@@6BA@@@"
+ // MANGLING-DAG: @"??_7W@Test9@@6BD@@@"
+ // MANGLING-DAG: @"??_7W@Test9@@6BX@1@@"
+
+ // MANGLING-DAG: @"??_7W@Test9@@6B@"
+ // MANGLING-DAG: @"??_7W@Test9@@6BY@1@@"
+};
+
+W::W() {}
+
+struct T : Z, D, virtual A, virtual B {
+ // CHECK-LABEL: VFTable for 'Test9::Y' in 'Test9::Z' in 'Test9::T' (1 entry).
+ // CHECK-NEXT: 0 | void Test9::T::h()
+
+ // CHECK-LABEL: VFTable for 'A' in 'Test9::X' in 'Test9::Y' in 'Test9::Z' in 'Test9::T' (2 entries).
+ // CHECK-NEXT: 0 | void Test9::T::f()
+ // CHECK-NEXT: 1 | void Test9::T::z()
+
+ // CHECK-LABEL: VFTable for 'B' in 'Test9::Z' in 'Test9::T' (1 entry).
+ // CHECK-NEXT: 0 | void Test9::T::g()
+
+ // CHECK-LABEL: VFTable for 'D' in 'Test9::T' (1 entry).
+ // CHECK-NEXT: 0 | void Test9::T::h()
+ // CHECK-NEXT: [this adjustment: -8 non-virtual]
+
+ // CHECK-LABEL: Thunks for 'void Test9::T::h()' (1 entry).
+ // CHECK-NEXT: 0 | [this adjustment: -8 non-virtual]
+
+ // CHECK-LABEL: VFTable for 'A' in 'D' in 'Test9::T' (2 entries).
+ // CHECK-NEXT: 0 | void Test9::T::f()
+ // CHECK-NEXT: [this adjustment: -8 non-virtual]
+ // CHECK-NEXT: 1 | void Test9::T::z()
+ // CHECK-NEXT: [this adjustment: -8 non-virtual]
+
+ // CHECK-LABEL: Thunks for 'void Test9::T::f()' (1 entry).
+ // CHECK-NEXT: 0 | [this adjustment: -8 non-virtual]
+
+ // CHECK-LABEL: Thunks for 'void Test9::T::z()' (1 entry).
+ // CHECK-NEXT: 0 | [this adjustment: -8 non-virtual]
+
+ // CHECK-LABEL: VFTable indices for 'Test9::T' (4 entries).
+ // CHECK-NEXT: via vfptr at offset 0
+ // CHECK-NEXT: 0 | void Test9::T::h()
+ // CHECK-NEXT: via vbtable index 1, vfptr at offset 0
+ // CHECK-NEXT: 0 | void Test9::T::f()
+ // CHECK-NEXT: 1 | void Test9::T::z()
+ // CHECK-NEXT: via vbtable index 2, vfptr at offset 0
+ // CHECK-NEXT: 0 | void Test9::T::g()
+
+ // MANGLING-DAG: @"??_7T@Test9@@6BA@@@"
+ // MANGLING-DAG: @"??_7T@Test9@@6BD@@@"
+ // MANGLING-DAG: @"??_7T@Test9@@6BX@1@@"
+
+ // MANGLING-DAG: @"??_7T@Test9@@6B@"
+ // MANGLING-DAG: @"??_7T@Test9@@6BY@1@@"
+
+ virtual void f();
+ virtual void g();
+ virtual void h();
+ virtual void z();
+};
+
+T t;
+void use(T *obj) { obj->f(); }
+}
+
+namespace Test10 {
+struct X : virtual C, virtual A {
+ // CHECK-LABEL: VFTable for 'A' in 'C' in 'Test10::X' (2 entries).
+ // CHECK-NEXT: 0 | void Test10::X::f()
+ // CHECK-NEXT: 1 | void A::z()
+
+ // CHECK-LABEL: VFTable indices for 'Test10::X' (1 entry).
+ // CHECK-NEXT: via vbtable index 1, vfptr at offset 0
+ // CHECK-NEXT: 0 | void Test10::X::f()
+ virtual void f();
+};
+
+void X::f() {}
+X x;
+void use(X *obj) { obj->f(); }
+}
+
+namespace Test11 {
+struct X : virtual A {};
+struct Y { virtual void g(); };
+
+struct Z : virtual X, Y {
+ // MANGLING-DAG: @"??_7Z@Test11@@6BY@1@@"
+ // MANGLING-DAG: @"??_7Z@Test11@@6BX@1@@"
+};
+
+Z z;
+
+struct W : virtual X, A {};
+
+// Used to crash, PR17748.
+W w;
+}
+
+namespace Test12 {
+struct X : B, A { };
+
+struct Y : X {
+ virtual void f(); // Overrides A::f.
+};
+
+struct Z : virtual Y {
+ // CHECK-LABEL: VFTable for 'A' in 'Test12::X' in 'Test12::Y' in 'Test12::Z' (2 entries).
+ // CHECK-NEXT: 0 | void Test12::Y::f()
+ // CHECK-NEXT: 1 | void A::z()
+
+ int z;
+ // MANGLING-DAG: @"??_7Z@Test12@@6BA@@@" = {{.*}}@"?f@Y@Test12@@UAEXXZ"
+};
+
+struct W : Z {
+ // CHECK-LABEL: VFTable for 'A' in 'Test12::X' in 'Test12::Y' in 'Test12::Z' in 'Test12::W' (2 entries).
+ // CHECK-NEXT: 0 | void Test12::Y::f()
+ // CHECK-NEXT: 1 | void A::z()
+ W();
+
+ int w;
+ // MANGLING-DAG: @"??_7W@Test12@@6BA@@@" = {{.*}}@"?f@Y@Test12@@UAEXXZ"
+};
+
+W::W() {}
+}
+
+namespace vdtors {
+struct X {
+ virtual ~X();
+ virtual void zzz();
+};
+
+struct Y : virtual X {
+ // CHECK-LABEL: VFTable for 'vdtors::X' in 'vdtors::Y' (2 entries).
+ // CHECK-NEXT: 0 | vdtors::Y::~Y() [scalar deleting]
+ // CHECK-NEXT: 1 | void vdtors::X::zzz()
+
+ // CHECK-NOT: Thunks for 'vdtors::Y::~Y()'
+ virtual ~Y();
+};
+
+Y y;
+void use(Y *obj) { delete obj; }
+
+struct Z {
+ virtual void z();
+};
+
+struct W : Z, X {
+ // Implicit virtual dtor.
+};
+
+struct U : virtual W {
+ // CHECK-LABEL: VFTable for 'vdtors::Z' in 'vdtors::W' in 'vdtors::U' (1 entry).
+ // CHECK-NEXT: 0 | void vdtors::Z::z()
+
+ // CHECK-LABEL: VFTable for 'vdtors::X' in 'vdtors::W' in 'vdtors::U' (2 entries).
+ // CHECK-NEXT: 0 | vdtors::U::~U() [scalar deleting]
+ // CHECK-NEXT: [this adjustment: -4 non-virtual]
+ // CHECK-NEXT: 1 | void vdtors::X::zzz()
+
+ // CHECK-LABEL: Thunks for 'vdtors::U::~U()' (1 entry).
+ // CHECK-NEXT: 0 | [this adjustment: -4 non-virtual]
+
+ // CHECK-LABEL: VFTable indices for 'vdtors::U' (1 entry).
+ // CHECK-NEXT: -- accessible via vbtable index 1, vfptr at offset 4 --
+ // CHECK-NEXT: 0 | vdtors::U::~U() [scalar deleting]
+ virtual ~U();
+};
+
+U u;
+void use(U *obj) { delete obj; }
+
+struct V : virtual W {
+ // CHECK-LABEL: VFTable for 'vdtors::Z' in 'vdtors::W' in 'vdtors::V' (1 entry).
+ // CHECK-NEXT: 0 | void vdtors::Z::z()
+
+ // CHECK-LABEL: VFTable for 'vdtors::X' in 'vdtors::W' in 'vdtors::V' (2 entries).
+ // CHECK-NEXT: 0 | vdtors::V::~V() [scalar deleting]
+ // CHECK-NEXT: [this adjustment: -4 non-virtual]
+ // CHECK-NEXT: 1 | void vdtors::X::zzz()
+
+ // CHECK-LABEL: Thunks for 'vdtors::V::~V()' (1 entry).
+ // CHECK-NEXT: 0 | [this adjustment: -4 non-virtual]
+
+ // CHECK-LABEL: VFTable indices for 'vdtors::V' (1 entry).
+ // CHECK-NEXT: -- accessible via vbtable index 1, vfptr at offset 4 --
+ // CHECK-NEXT: 0 | vdtors::V::~V() [scalar deleting]
+};
+
+V v;
+void use(V *obj) { delete obj; }
+
+struct T : virtual X {
+ virtual ~T();
+};
+
+struct P : T, Y {
+ // CHECK-LABEL: VFTable for 'vdtors::X' in 'vdtors::T' in 'vdtors::P' (2 entries).
+ // CHECK-NEXT: 0 | vdtors::P::~P() [scalar deleting]
+ // CHECK-NEXT: 1 | void vdtors::X::zzz()
+
+ // CHECK-NOT: Thunks for 'vdtors::P::~P()'
+ virtual ~P();
+};
+
+P p;
+void use(P *obj) { delete obj; }
+
+struct Q {
+ virtual ~Q();
+};
+
+// PR19172: Yet another diamond we miscompiled.
+struct R : virtual Q, X {
+ // CHECK-LABEL: VFTable for 'vdtors::Q' in 'vdtors::R' (1 entry).
+ // CHECK-NEXT: 0 | vdtors::R::~R() [scalar deleting]
+ // CHECK-NEXT: [this adjustment: -8 non-virtual]
+
+ // CHECK-LABEL: Thunks for 'vdtors::R::~R()' (1 entry).
+ // CHECK-NEXT: 0 | [this adjustment: -8 non-virtual]
+
+ // CHECK-LABEL: VFTable for 'vdtors::X' in 'vdtors::R' (2 entries).
+ // CHECK-NEXT: 0 | vdtors::R::~R() [scalar deleting]
+ // CHECK-NEXT: 1 | void vdtors::X::zzz()
+
+ // CHECK-LABEL: VFTable indices for 'vdtors::R' (1 entry).
+ // CHECK-NEXT: 0 | vdtors::R::~R() [scalar deleting]
+ virtual ~R();
+};
+
+R r;
+void use(R *obj) { delete obj; }
+}
+
+namespace return_adjustment {
+
+struct X : virtual A {
+ virtual void f();
+};
+
+struct Y : virtual A, virtual X {
+ virtual void f();
+};
+
+struct Z {
+ virtual A* foo();
+};
+
+struct W : Z {
+ // CHECK-LABEL: VFTable for 'return_adjustment::Z' in 'return_adjustment::W' (2 entries).
+ // CHECK-NEXT: 0 | return_adjustment::X *return_adjustment::W::foo()
+ // CHECK-NEXT: [return adjustment (to type 'struct A *'): vbase #1, 0 non-virtual]
+ // CHECK-NEXT: 1 | return_adjustment::X *return_adjustment::W::foo()
+
+ // CHECK-LABEL: Thunks for 'return_adjustment::X *return_adjustment::W::foo()' (1 entry).
+ // CHECK-NEXT: 0 | [return adjustment (to type 'struct A *'): vbase #1, 0 non-virtual]
+
+ // CHECK-LABEL: VFTable indices for 'return_adjustment::W' (1 entry).
+ // CHECK-NEXT: 1 | return_adjustment::X *return_adjustment::W::foo()
+
+ virtual X* foo();
+};
+
+W w;
+void use(W *obj) { obj->foo(); }
+
+struct T : W {
+ // CHECK-LABEL: VFTable for 'return_adjustment::Z' in 'return_adjustment::W' in 'return_adjustment::T' (3 entries).
+ // CHECK-NEXT: 0 | return_adjustment::Y *return_adjustment::T::foo()
+ // CHECK-NEXT: [return adjustment (to type 'struct A *'): vbase #1, 0 non-virtual]
+ // CHECK-NEXT: 1 | return_adjustment::Y *return_adjustment::T::foo()
+ // CHECK-NEXT: [return adjustment (to type 'struct return_adjustment::X *'): vbase #2, 0 non-virtual]
+ // CHECK-NEXT: 2 | return_adjustment::Y *return_adjustment::T::foo()
+
+ // CHECK-LABEL: Thunks for 'return_adjustment::Y *return_adjustment::T::foo()' (2 entries).
+ // CHECK-NEXT: 0 | [return adjustment (to type 'struct A *'): vbase #1, 0 non-virtual]
+ // CHECK-NEXT: 1 | [return adjustment (to type 'struct return_adjustment::X *'): vbase #2, 0 non-virtual]
+
+ // CHECK-LABEL: VFTable indices for 'return_adjustment::T' (1 entry).
+ // CHECK-NEXT: 2 | return_adjustment::Y *return_adjustment::T::foo()
+
+ virtual Y* foo();
+};
+
+T t;
+void use(T *obj) { obj->foo(); }
+
+struct U : virtual A {
+ virtual void g(); // adds a vfptr
+};
+
+struct V : Z {
+ // CHECK-LABEL: VFTable for 'return_adjustment::Z' in 'return_adjustment::V' (2 entries).
+ // CHECK-NEXT: 0 | return_adjustment::U *return_adjustment::V::foo()
+ // CHECK-NEXT: [return adjustment (to type 'struct A *'): vbptr at offset 4, vbase #1, 0 non-virtual]
+ // CHECK-NEXT: 1 | return_adjustment::U *return_adjustment::V::foo()
+
+ // CHECK-LABEL: Thunks for 'return_adjustment::U *return_adjustment::V::foo()' (1 entry).
+ // CHECK-NEXT: 0 | [return adjustment (to type 'struct A *'): vbptr at offset 4, vbase #1, 0 non-virtual]
+
+ // CHECK-LABEL: VFTable indices for 'return_adjustment::V' (1 entry).
+ // CHECK-NEXT: 1 | return_adjustment::U *return_adjustment::V::foo()
+
+ virtual U* foo();
+};
+
+V v;
+void use(V *obj) { obj->foo(); }
+}
+
+namespace pr17748 {
+struct A {
+ virtual void f() {}
+};
+
+struct B : virtual A {
+ B() {}
+};
+
+struct C : virtual B, A {
+ C() {}
+};
+C c;
+
+// MANGLING-DAG: @"??_7A@pr17748@@6B@"
+// MANGLING-DAG: @"??_7B@pr17748@@6B@"
+// MANGLING-DAG: @"??_7C@pr17748@@6BA@1@@"
+// MANGLING-DAG: @"??_7C@pr17748@@6BB@1@@"
+}
+
+namespace pr19066 {
+struct X : virtual B {};
+
+struct Y : virtual X, B {
+ Y();
+ // CHECK-LABEL: VFTable for 'B' in 'pr19066::X' in 'pr19066::Y' (1 entry).
+ // CHECK-NEXT: 0 | void B::g()
+
+ // CHECK-LABEL: VFTable for 'B' in 'pr19066::Y' (1 entry).
+ // CHECK-NEXT: 0 | void B::g()
+};
+
+Y::Y() {}
+}
+
+namespace pr19240 {
+struct A {
+ virtual void c();
+};
+
+struct B : virtual A {
+ virtual void c();
+};
+
+struct C { };
+
+struct D : virtual A, virtual C, B {};
+
+D obj;
+
+// Each MDC only has one vftable.
+
+// MANGLING-DAG: @"??_7D@pr19240@@6B@"
+// MANGLING-DAG: @"??_7A@pr19240@@6B@"
+// MANGLING-DAG: @"??_7B@pr19240@@6B@"
+
+}
+
+namespace pr19408 {
+// This test is a non-vtordisp version of the reproducer for PR19408.
+struct X : virtual A {
+ int x;
+};
+
+struct Y : X {
+ virtual void f();
+ int y;
+};
+
+struct Z : Y {
+ // CHECK-LABEL: VFTable for 'A' in 'pr19408::X' in 'pr19408::Y' in 'pr19408::Z' (2 entries).
+ // CHECK-NEXT: 0 | void pr19408::Y::f()
+ // CHECK-NEXT: [this adjustment: -4 non-virtual]
+ // CHECK-NEXT: 1 | void A::z()
+
+ Z();
+ int z;
+ // MANGLING-DAG: @"??_7Z@pr19408@@6B@" = {{.*}}@"?f@Y@pr19408@@W3AEXXZ"
+};
+
+Z::Z() {}
+
+struct W : B, Y {
+ // CHECK-LABEL: VFTable for 'A' in 'pr19408::X' in 'pr19408::Y' in 'pr19408::W' (2 entries).
+ // CHECK-NEXT: 0 | void pr19408::Y::f()
+ // CHECK-NEXT: [this adjustment: -4 non-virtual]
+ // CHECK-NEXT: 1 | void A::z()
+
+ W();
+ int w;
+ // MANGLING-DAG: @"??_7W@pr19408@@6BY@1@@" = {{.*}}@"?f@Y@pr19408@@W3AEXXZ"
+};
+
+W::W() {}
+}
+
+namespace Test13 {
+struct A {
+ virtual void f();
+};
+struct __declspec(dllexport) B : virtual A {
+ virtual void f() = 0;
+ // MANGLING-DAG: @"??_7B@Test13@@6B@" = weak_odr dllexport unnamed_addr constant { [1 x i8*] } { [1 x i8*] [i8* bitcast (void ()* @_purecall to i8*)] }
+};
+}
+
+namespace pr21031_1 {
+// This ordering of base specifiers regressed in r202425.
+struct A { virtual void f(void); };
+struct B : virtual A { virtual void g(void); };
+struct C : virtual A, B { C(); };
+C::C() {}
+
+// CHECK-LABEL: VFTable for 'pr21031_1::A' in 'pr21031_1::B' in 'pr21031_1::C' (1 entry)
+// CHECK-NEXT: 0 | void pr21031_1::A::f()
+
+// CHECK-LABEL: VFTable for 'pr21031_1::B' in 'pr21031_1::C' (1 entry)
+// CHECK-NEXT: 0 | void pr21031_1::B::g()
+
+// MANGLING-DAG: @"??_7C@pr21031_1@@6BB@1@@" = {{.*}} constant { [1 x i8*] }
+// MANGLING-DAG: @"??_7C@pr21031_1@@6B@" = {{.*}} constant { [1 x i8*] }
+}
+
+namespace pr21031_2 {
+struct A { virtual void f(void); };
+struct B : virtual A { virtual void g(void); };
+struct C : B, virtual A { C(); };
+C::C() {}
+
+// CHECK-LABEL: VFTable for 'pr21031_2::B' in 'pr21031_2::C' (1 entry)
+// CHECK-NEXT: 0 | void pr21031_2::B::g()
+
+// CHECK-LABEL: VFTable for 'pr21031_2::A' in 'pr21031_2::B' in 'pr21031_2::C' (1 entry)
+// CHECK-NEXT: 0 | void pr21031_2::A::f()
+
+// MANGLING-DAG: @"??_7C@pr21031_2@@6BA@1@@" = {{.*}} constant { [1 x i8*] }
+// MANGLING-DAG: @"??_7C@pr21031_2@@6BB@1@@" = {{.*}} constant { [1 x i8*] }
+}
+
+namespace pr21062_1 {
+struct A { virtual void f(); };
+struct B {};
+struct C : virtual B {};
+struct D : virtual C, virtual B, virtual A { D();};
+D::D() {}
+
+// CHECK-LABEL: VFTable for 'pr21062_1::A' in 'pr21062_1::D' (1 entry)
+// CHECK-NEXT: 0 | void pr21062_1::A::f()
+
+// MANGLING-DAG: @"??_7D@pr21062_1@@6B@" = {{.*}} constant { [1 x i8*] }
+}
+
+namespace pr21062_2 {
+struct A { virtual void f(); };
+struct B {};
+struct C : virtual B {};
+struct D : C, virtual B, virtual A { D(); };
+D::D() {}
+
+// CHECK-LABEL: VFTable for 'pr21062_2::A' in 'pr21062_2::D' (1 entry)
+// CHECK-NEXT: 0 | void pr21062_2::A::f()
+
+// MANGLING-DAG: @"??_7D@pr21062_2@@6B@" = {{.*}} constant { [1 x i8*] }
+}
+
+namespace pr21064 {
+struct A {};
+struct B { virtual void f(); };
+struct C : virtual A, virtual B {};
+struct D : virtual A, virtual C { D(); };
+D::D() {}
+// CHECK-LABEL: VFTable for 'pr21064::B' in 'pr21064::C' in 'pr21064::D' (1 entry)
+// CHECK-NEXT: 0 | void pr21064::B::f()
+
+// MANGLING-DAG: @"??_7D@pr21064@@6B@" = {{.*}} constant { [1 x i8*] }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-compatibility.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-compatibility.cpp
new file mode 100644
index 0000000..64d10a5
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-compatibility.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 %s -triple i686-pc-win32 -std=c++11 -fms-compatibility -emit-llvm -o - | FileCheck %s
+
+template <typename>
+struct S {
+ static const int x[];
+};
+
+template <>
+const int S<char>::x[] = {1};
+
+// CHECK-LABEL: @"?x@?$S@D@@2QBHB" = weak_odr dso_local constant [1 x i32] [i32 1], comdat
+
+template<class T>
+void destroy(T *p) {
+ p->~T();
+}
+
+extern "C" void f() {
+ int a;
+ destroy((void*)&a);
+}
+
+// CHECK-LABEL: define dso_local void @f()
+// CHECK: call void @"??$destroy@X@@YAXPAX@Z"
+// CHECK: ret void
+
+// CHECK-LABEL: define linkonce_odr dso_local void @"??$destroy@X@@YAXPAX@Z"(i8* %p)
+// The pseudo-dtor expr should not generate calls to anything.
+// CHECK-NOT: call
+// CHECK-NOT: invoke
+// CHECK: ret void
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-inaccessible-base.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-inaccessible-base.cpp
new file mode 100644
index 0000000..d8af8ef
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-inaccessible-base.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fms-compatibility -triple x86_64-windows-msvc %s -emit-llvm -o - | FileCheck %s
+
+// Make sure we choose the *direct* base path when doing these conversions.
+
+// CHECK: %struct.C = type { %struct.A, %struct.B }
+// CHECK: %struct.D = type { %struct.B, %struct.A }
+
+struct A { int a; };
+struct B : A { int b; };
+
+struct C : A, B { };
+extern "C" A *a_from_c(C *p) { return p; }
+// CHECK-LABEL: define dso_local %struct.A* @a_from_c(%struct.C* %{{.*}})
+// CHECK: bitcast %struct.C* %{{.*}} to %struct.A*
+
+struct D : B, A { };
+extern "C" A *a_from_d(D *p) { return p; }
+// CHECK-LABEL: define dso_local %struct.A* @a_from_d(%struct.D* %{{.*}})
+// CHECK: %[[p_i8:[^ ]*]] = bitcast %struct.D* %{{.*}} to i8*
+// CHECK: getelementptr inbounds i8, i8* %[[p_i8]], i64 8
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-interface.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-interface.cpp
new file mode 100644
index 0000000..74a5209
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-interface.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -std=c++11 -fms-extensions -Wno-microsoft -triple=i386-pc-windows-gnu -emit-llvm %s -o - | FileCheck %s
+
+__interface I {
+ int test() {
+ return 1;
+ }
+};
+
+struct S : I {
+ virtual int test() override {
+ return I::test();
+ }
+};
+
+int fn() {
+ S s;
+ return s.test();
+}
+
+// CHECK: @_ZTV1S = linkonce_odr dso_local unnamed_addr constant { [3 x i8*] } { [3 x i8*] [i8* null, i8* bitcast ({ i8*, i8*, i8* }* @_ZTI1S to i8*), i8* bitcast (i32 (%struct.S*)* @_ZN1S4testEv to i8*)] }
+
+// CHECK-LABEL: define dso_local i32 @_Z2fnv()
+// CHECK: call x86_thiscallcc void @_ZN1SC1Ev(%struct.S* %s)
+// CHECK: %{{[.0-9A-Z_a-z]+}} = call x86_thiscallcc i32 @_ZN1S4testEv(%struct.S* %s)
+
+// CHECK-LABEL: define linkonce_odr dso_local x86_thiscallcc void @_ZN1SC1Ev(%struct.S* %this)
+// CHECK: call x86_thiscallcc void @_ZN1SC2Ev(%struct.S* %{{[.0-9A-Z_a-z]+}})
+
+// CHECK-LABEL: define linkonce_odr dso_local x86_thiscallcc i32 @_ZN1S4testEv(%struct.S* %this)
+// CHECK: %{{[.0-9A-Z_a-z]+}} = call x86_thiscallcc i32 @_ZN1I4testEv(%__interface.I* %{{[.0-9A-Z_a-z]+}})
+
+// CHECK-LABEL: define linkonce_odr dso_local x86_thiscallcc void @_ZN1SC2Ev(%struct.S* %this)
+// CHECK: call x86_thiscallcc void @_ZN1IC2Ev(%__interface.I* %{{[.0-9A-Z_a-z]+}})
+// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTV1S, i32 0, inrange i32 0, i32 2) to i32 (...)**), i32 (...)*** %{{[.0-9A-Z_a-z]+}}
+
+// CHECK-LABEL: define linkonce_odr dso_local x86_thiscallcc void @_ZN1IC2Ev(%__interface.I* %this)
+// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTV1I, i32 0, inrange i32 0, i32 2) to i32 (...)**), i32 (...)*** %{{[.0-9A-Z_a-z]+}}
+
+// CHECK-LABEL: define linkonce_odr dso_local x86_thiscallcc i32 @_ZN1I4testEv(%__interface.I* %this)
+// CHECK: ret i32 1
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-new.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-new.cpp
new file mode 100644
index 0000000..01b09609
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-new.cpp
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -triple i686-pc-win32 -fms-compatibility %s -emit-llvm -o - | FileCheck %s
+
+#include <stddef.h>
+
+struct arbitrary_t {} arbitrary;
+void *operator new(size_t size, arbitrary_t);
+
+struct arbitrary2_t {} arbitrary2;
+void *operator new[](size_t size, arbitrary2_t);
+
+namespace PR13164 {
+ void f() {
+ // MSVC will fall back on the non-array operator new.
+ void *a;
+ int *p = new(arbitrary) int[4];
+ // CHECK: call i8* @"??2@YAPAXIUarbitrary_t@@@Z"(i32 16, %struct.arbitrary_t*
+ }
+
+ struct S {
+ void *operator new[](size_t size, arbitrary_t);
+ };
+
+ void g() {
+ S *s = new(arbitrary) S[2];
+ // CHECK: call i8* @"??_US@PR13164@@SAPAXIUarbitrary_t@@@Z"(i32 2, %struct.arbitrary_t*
+ S *s1 = new(arbitrary) S;
+ // CHECK: call i8* @"??2@YAPAXIUarbitrary_t@@@Z"(i32 1, %struct.arbitrary_t*
+ }
+
+ struct T {
+ void *operator new(size_t size, arbitrary2_t);
+ };
+
+ void h() {
+ // This should still call the global operator new[].
+ T *t = new(arbitrary2) T[2];
+ // CHECK: call i8* @"??_U@YAPAXIUarbitrary2_t@@@Z"(i32 2, %struct.arbitrary2_t*
+ }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-no-rtti-data.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-no-rtti-data.cpp
new file mode 100644
index 0000000..3d218ed
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-no-rtti-data.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 %s -fno-rtti-data -triple=i386-pc-win32 -o - -emit-llvm | FileCheck %s
+
+// vftable shouldn't have RTTI data in it.
+// CHECK-NOT: @"??_R4S@@6B@"
+// CHECK: @"??_7S@@6B@" = linkonce_odr unnamed_addr constant { [1 x i8*] } { [1 x i8*] [i8* bitcast ({{.*}} @"??_GS@@UAEPAXI@Z" to i8*)] }, comdat
+
+struct type_info;
+namespace std { using ::type_info; }
+
+struct S {
+ virtual ~S();
+} s;
+
+struct U : S {
+ virtual ~U();
+};
+
+extern S *getS();
+
+const std::type_info &ti = typeid(*getS());
+const U &u = dynamic_cast<U &>(*getS());
+// CHECK: call i8* @__RTDynamicCast(i8* %{{.+}}, i32 0, i8* bitcast ({{.*}} @"??_R0?AUS@@@8" to i8*), i8* bitcast ({{.*}} @"??_R0?AUU@@@8" to i8*), i32 1)
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-templ-uuidof.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-templ-uuidof.cpp
new file mode 100644
index 0000000..7d40a15
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-templ-uuidof.cpp
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -DDEFINE_GUID -triple=i386-pc-win32 -fms-extensions | FileCheck %s
+
+struct _GUID;
+
+template <typename>
+struct X {
+};
+
+struct __declspec(uuid("{AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA}")) A {};
+
+struct B {};
+
+template <>
+struct __declspec(uuid("{BBBBBBBB-BBBB-BBBB-BBBB-BBBBBBBBBBBB}")) X<B> {};
+
+struct __declspec(uuid("{CCCCCCCC-CCCC-CCCC-CCCC-CCCCCCCCCCCC}")) C {};
+
+// CHECK-DAG: @_GUID_aaaaaaaa_aaaa_aaaa_aaaa_aaaaaaaaaaaa = linkonce_odr dso_local
+
+const _GUID &xa = __uuidof(X<A>);
+// CHECK-DAG: @"?xa@@3ABU_GUID@@B" = {{.*}} @_GUID_aaaaaaaa_aaaa_aaaa_aaaa_aaaaaaaaaaaa
+
+const _GUID &xb = __uuidof(X<B>);
+// CHECK-DAG: @"?xb@@3ABU_GUID@@B" = {{.*}} @_GUID_bbbbbbbb_bbbb_bbbb_bbbb_bbbbbbbbbbbb
+const _GUID &xc = __uuidof(X<C>);
+// CHECK-DAG: @"?xc@@3ABU_GUID@@B" = {{.*}} @_GUID_cccccccc_cccc_cccc_cccc_cccccccccccc
+
+template <>
+struct __declspec(uuid("{DDDDDDDD-DDDD-DDDD-DDDD-DDDDDDDDDDDD}")) X<C> {};
+
+template <typename>
+struct __declspec(uuid("{EEEEEEEE-EEEE-EEEE-EEEE-EEEEEEEEEEEE}")) Y {
+};
+
+const _GUID &xd = __uuidof(X<C>);
+// CHECK-DAG: @"?xd@@3ABU_GUID@@B" = {{.*}} @_GUID_dddddddd_dddd_dddd_dddd_dddddddddddd
+
+const _GUID &yd = __uuidof(Y<X<C> >);
+// CHECK-DAG: @"?yd@@3ABU_GUID@@B" = {{.*}} @_GUID_dddddddd_dddd_dddd_dddd_dddddddddddd
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-uuidof-mangling.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-uuidof-mangling.cpp
new file mode 100644
index 0000000..9019aa8
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-uuidof-mangling.cpp
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple x86_64-unknown-unknown -fms-extensions | FileCheck %s
+// rdar://17784718
+
+typedef struct _GUID
+{
+ unsigned int Data1;
+ unsigned short Data2;
+ unsigned short Data3;
+ unsigned char Data4[ 8 ];
+} GUID;
+
+
+template < typename T, const GUID & T_iid = __uuidof(T)>
+class UUIDTest
+{
+public:
+ UUIDTest() { }
+};
+
+struct __declspec(uuid("EAFA1952-66F8-438B-8FBA-AF1BBAE42191")) TestStruct
+{
+ int foo;
+};
+
+template <class T> void test_uuidofType(void *arg[sizeof(__uuidof(T))] = 0) {}
+
+template <class T> void test_uuidofExpr(void *arg[sizeof(__uuidof(T::member))] = 0) {}
+
+struct HasMember { typedef TestStruct member; };
+
+int main(int argc, const char * argv[])
+{
+
+ UUIDTest<TestStruct> uuidof_test;
+ test_uuidofType<TestStruct>();
+ test_uuidofExpr<HasMember>();
+ return 0;
+}
+
+// CHECK: define i32 @main
+// CHECK: call void @_ZN8UUIDTestI10TestStructXu8__uuidoftS0_EEC1Ev
+// CHECK: call void @_Z15test_uuidofTypeI10TestStructEvPPv(i8** null)
+// CHECK: call void @_Z15test_uuidofExprI9HasMemberEvPPv(i8** null)
+
+// CHECK: define linkonce_odr void @_ZN8UUIDTestI10TestStructXu8__uuidoftS0_EEC1Ev
+// CHECK: define linkonce_odr void @_Z15test_uuidofTypeI10TestStructEvPPv
+// CHECK: define linkonce_odr void @_Z15test_uuidofExprI9HasMemberEvPPv
+// CHECK: define linkonce_odr void @_ZN8UUIDTestI10TestStructXu8__uuidoftS0_EEC2Ev
diff --git a/src/llvm-project/clang/test/CodeGenCXX/microsoft-uuidof.cpp b/src/llvm-project/clang/test/CodeGenCXX/microsoft-uuidof.cpp
new file mode 100644
index 0000000..f8d2da7
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/microsoft-uuidof.cpp
@@ -0,0 +1,123 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -DDEFINE_GUID -triple=i386-pc-linux -fms-extensions | FileCheck %s --check-prefix=CHECK-DEFINE-GUID
+// RUN: %clang_cc1 -emit-llvm %s -o - -DDEFINE_GUID -DBRACKET_ATTRIB -triple=i386-pc-linux -fms-extensions | FileCheck %s --check-prefix=CHECK-DEFINE-GUID
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-linux -fms-extensions | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-pc-linux -fms-extensions | FileCheck %s --check-prefix=CHECK-64
+// RUN: %clang_cc1 -emit-llvm %s -o - -DDEFINE_GUID -DWRONG_GUID -triple=i386-pc-linux -fms-extensions | FileCheck %s --check-prefix=CHECK-DEFINE-WRONG-GUID
+
+#ifdef DEFINE_GUID
+struct _GUID {
+#ifdef WRONG_GUID
+ unsigned int SomethingWentWrong;
+#else
+ unsigned long Data1;
+ unsigned short Data2;
+ unsigned short Data3;
+ unsigned char Data4[8];
+#endif
+};
+#endif
+typedef struct _GUID GUID;
+
+#ifdef BRACKET_ATTRIB
+[uuid(12345678-1234-1234-1234-1234567890aB)] struct S1 { } s1;
+[uuid(87654321-4321-4321-4321-ba0987654321)] struct S2 { };
+[uuid({12345678-1234-1234-1234-1234567890ac})] struct Curly;
+[uuid({12345678-1234-1234-1234-1234567890ac})] struct Curly;
+#else
+struct __declspec(uuid("12345678-1234-1234-1234-1234567890aB")) S1 { } s1;
+struct __declspec(uuid("87654321-4321-4321-4321-ba0987654321")) S2 { };
+struct __declspec(uuid("{12345678-1234-1234-1234-1234567890ac}")) Curly;
+struct __declspec(uuid("{12345678-1234-1234-1234-1234567890ac}")) Curly;
+#endif
+
+#ifdef DEFINE_GUID
+// Make sure we can properly generate code when the UUID has curly braces on it.
+GUID thing = __uuidof(Curly);
+// CHECK-DEFINE-GUID: @thing = global %struct._GUID zeroinitializer, align 4
+// CHECK-DEFINE-WRONG-GUID: @thing = global %struct._GUID zeroinitializer, align 4
+
+// This gets initialized in a static initializer.
+// CHECK-DEFINE-GUID: @g = global %struct._GUID zeroinitializer, align 4
+// CHECK-DEFINE-WRONG-GUID: @g = global %struct._GUID zeroinitializer, align 4
+GUID g = __uuidof(S1);
+#endif
+
+// First global use of __uuidof(S1) forces the creation of the global.
+// CHECK: @_GUID_12345678_1234_1234_1234_1234567890ab = linkonce_odr constant { i32, i16, i16, [8 x i8] } { i32 305419896, i16 4660, i16 4660, [8 x i8] c"\124\124Vx\90\AB" }, comdat
+// CHECK: @gr = constant %struct._GUID* bitcast ({ i32, i16, i16, [8 x i8] }* @_GUID_12345678_1234_1234_1234_1234567890ab to %struct._GUID*), align 4
+// CHECK-64: @gr = constant %struct._GUID* bitcast ({ i32, i16, i16, [8 x i8] }* @_GUID_12345678_1234_1234_1234_1234567890ab to %struct._GUID*), align 8
+const GUID& gr = __uuidof(S1);
+
+// CHECK: @gp = global %struct._GUID* bitcast ({ i32, i16, i16, [8 x i8] }* @_GUID_12345678_1234_1234_1234_1234567890ab to %struct._GUID*), align 4
+const GUID* gp = &__uuidof(S1);
+
+// CHECK: @cp = global %struct._GUID* bitcast ({ i32, i16, i16, [8 x i8] }* @_GUID_12345678_1234_1234_1234_1234567890ac to %struct._GUID*), align 4
+const GUID* cp = &__uuidof(Curly);
+
+// Special case: _uuidof(0)
+// CHECK: @zeroiid = constant %struct._GUID* bitcast ({ i32, i16, i16, [8 x i8] }* @_GUID_00000000_0000_0000_0000_000000000000 to %struct._GUID*), align 4
+const GUID& zeroiid = __uuidof(0);
+
+// __uuidof(S2) hasn't been used globally yet, so it's emitted when it's used
+// in a function and is emitted at the end of the globals section.
+// CHECK: @_GUID_87654321_4321_4321_4321_ba0987654321 = linkonce_odr constant { i32, i16, i16, [8 x i8] } { i32 -2023406815, i16 17185, i16 17185, [8 x i8] c"C!\BA\09\87eC!" }, comdat
+
+// The static initializer for thing.
+// CHECK-DEFINE-GUID: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 bitcast (%struct._GUID* @thing to i8*), i8* align 4 bitcast ({ i32, i16, i16, [8 x i8] }* @_GUID_12345678_1234_1234_1234_1234567890ac to i8*), i32 16, i1 false)
+// CHECK-DEFINE-WRONG-GUID: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 bitcast (%struct._GUID* @thing to i8*), i8* align 4 bitcast ({ i32, i16, i16, [8 x i8] }* @_GUID_12345678_1234_1234_1234_1234567890ac to i8*), i32 4, i1 false)
+
+// The static initializer for g.
+// CHECK-DEFINE-GUID: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 bitcast (%struct._GUID* @g to i8*), i8* align 4 bitcast ({ i32, i16, i16, [8 x i8] }* @_GUID_12345678_1234_1234_1234_1234567890ab to i8*), i32 16, i1 false)
+// CHECK-DEFINE-WRONG-GUID: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 bitcast (%struct._GUID* @g to i8*), i8* align 4 bitcast ({ i32, i16, i16, [8 x i8] }* @_GUID_12345678_1234_1234_1234_1234567890ab to i8*), i32 4, i1 false)
+
+#ifdef DEFINE_GUID
+void fun() {
+ // CHECK-DEFINE-GUID: %s1_1 = alloca %struct._GUID, align 4
+ // CHECK-DEFINE-WRONG-GUID: %s1_1 = alloca %struct._GUID, align 4
+ // CHECK-DEFINE-GUID: %s1_2 = alloca %struct._GUID, align 4
+ // CHECK-DEFINE-WRONG-GUID: %s1_2 = alloca %struct._GUID, align 4
+ // CHECK-DEFINE-GUID: %s1_3 = alloca %struct._GUID, align 4
+ // CHECK-DEFINE-WRONG-GUID: %s1_3 = alloca %struct._GUID, align 4
+
+ // CHECK-DEFINE-GUID: [[U1:%.+]] = bitcast %struct._GUID* %s1_1 to i8*
+ // CHECK-DEFINE-WRONG-GUID: [[U1:%.+]] = bitcast %struct._GUID* %s1_1 to i8*
+ // CHECK-DEFINE-GUID: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 [[U1]], i8* align 4 bitcast ({ i32, i16, i16, [8 x i8] }* @_GUID_12345678_1234_1234_1234_1234567890ab to i8*), i32 16, i1 false)
+ // CHECK-DEFINE-WRONG-GUID: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 [[U1]], i8* align 4 bitcast ({ i32, i16, i16, [8 x i8] }* @_GUID_12345678_1234_1234_1234_1234567890ab to i8*), i32 4, i1 false)
+ GUID s1_1 = __uuidof(S1);
+
+ // CHECK-DEFINE-GUID: [[U2:%.+]] = bitcast %struct._GUID* %s1_2 to i8*
+ // CHECK-DEFINE-WRONG-GUID: [[U2:%.+]] = bitcast %struct._GUID* %s1_2 to i8*
+ // CHECK-DEFINE-GUID: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 [[U2]], i8* align 4 bitcast ({ i32, i16, i16, [8 x i8] }* @_GUID_12345678_1234_1234_1234_1234567890ab to i8*), i32 16, i1 false)
+ // CHECK-DEFINE-WRONG-GUID: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 [[U2]], i8* align 4 bitcast ({ i32, i16, i16, [8 x i8] }* @_GUID_12345678_1234_1234_1234_1234567890ab to i8*), i32 4, i1 false)
+ GUID s1_2 = __uuidof(S1);
+
+ // CHECK-DEFINE-GUID: [[U3:%.+]] = bitcast %struct._GUID* %s1_3 to i8*
+ // CHECK-DEFINE-WRONG-GUID: [[U3:%.+]] = bitcast %struct._GUID* %s1_3 to i8*
+ // CHECK-DEFINE-GUID: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 [[U3]], i8* align 4 bitcast ({ i32, i16, i16, [8 x i8] }* @_GUID_12345678_1234_1234_1234_1234567890ab to i8*), i32 16, i1 false)
+ // CHECK-DEFINE-WRONG-GUID: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 [[U3]], i8* align 4 bitcast ({ i32, i16, i16, [8 x i8] }* @_GUID_12345678_1234_1234_1234_1234567890ab to i8*), i32 4, i1 false)
+ GUID s1_3 = __uuidof(s1);
+}
+#endif
+
+void gun() {
+#ifdef DEFINE_GUID
+ // CHECK-DEFINE-GUID: %s2_1 = alloca %struct._GUID, align 4
+ // CHECK-DEFINE-WRONG-GUID: %s2_1 = alloca %struct._GUID, align 4
+ // CHECK-DEFINE-GUID: %s2_2 = alloca %struct._GUID, align 4
+ // CHECK-DEFINE-WRONG-GUID: %s2_2 = alloca %struct._GUID, align 4
+ GUID s2_1 = __uuidof(S2);
+ GUID s2_2 = __uuidof(S2);
+#endif
+ // CHECK: %r = alloca %struct._GUID*, align 4
+ // CHECK: %p = alloca %struct._GUID*, align 4
+ // CHECK: %zeroiid = alloca %struct._GUID*, align 4
+
+ // CHECK: store %struct._GUID* bitcast ({ i32, i16, i16, [8 x i8] }* @_GUID_87654321_4321_4321_4321_ba0987654321 to %struct._GUID*), %struct._GUID** %r, align 4
+ const GUID& r = __uuidof(S2);
+ // CHECK: store %struct._GUID* bitcast ({ i32, i16, i16, [8 x i8] }* @_GUID_87654321_4321_4321_4321_ba0987654321 to %struct._GUID*), %struct._GUID** %p, align 4
+ const GUID* p = &__uuidof(S2);
+
+ // Special case _uuidof(0), local scope version.
+ // CHECK: store %struct._GUID* bitcast ({ i32, i16, i16, [8 x i8] }* @_GUID_00000000_0000_0000_0000_000000000000 to %struct._GUID*), %struct._GUID** %zeroiid, align 4
+ const GUID& zeroiid = __uuidof(0);
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mingw-new-abi.cpp b/src/llvm-project/clang/test/CodeGenCXX/mingw-new-abi.cpp
new file mode 100644
index 0000000..fe98a1f
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mingw-new-abi.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -emit-llvm -triple i386-pc-mingw32 %s -o - | FileCheck --check-prefix=MINGW %s
+// RUN: %clang_cc1 -emit-llvm -triple i386-pc-cygwin %s -o - | FileCheck --check-prefix=CYGWIN %s
+
+namespace test1 {
+ struct foo {
+ // MINGW: declare dso_local x86_thiscallcc void @_ZN5test13foo1fEv
+ // CYGWIN: declare dso_local void @_ZN5test13foo1fEv
+ void f();
+ };
+ void g(foo *x) {
+ x->f();
+ }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mingw-w64-exceptions.c b/src/llvm-project/clang/test/CodeGenCXX/mingw-w64-exceptions.c
new file mode 100644
index 0000000..e980ebd
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mingw-w64-exceptions.c
@@ -0,0 +1,22 @@
+// RUN: %clang -target x86_64-windows-gnu -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SEH
+// RUN: %clang -target i686-windows-gnu -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-DWARF
+
+// RUN: %clang -target x86_64-windows-gnu -fsjlj-exceptions -c %s -### 2>&1 | \
+// RUN: FileCheck %s --check-prefix=CHECK-SJLJ
+
+// RUN: %clang -target x86_64-windows-gnu -fdwarf-exceptions -c %s -### 2>&1 | \
+// RUN: FileCheck %s --check-prefix=CHECK-DWARF
+
+// RUN: %clang -target x86_64-windows-gnu -fsjlj-exceptions -fseh-exceptions -c %s -### 2>&1 | \
+// RUN: FileCheck %s --check-prefix=CHECK-SEH
+
+// RUN: %clang -target x86_64-windows-gnu -fseh-exceptions -fsjlj-exceptions -c %s -### 2>&1 | \
+// RUN: FileCheck %s --check-prefix=CHECK-SJLJ
+
+// RUN: %clang -target x86_64-windows-gnu -fseh-exceptions -fdwarf-exceptions -c %s -### 2>&1 | \
+// RUN: FileCheck %s --check-prefix=CHECK-DWARF
+
+// CHECK-SEH: "-fseh-exceptions"
+// CHECK-SJLJ: "-fsjlj-exceptions"
+// CHECK-DWARF-NOT: "-fsjlj-exceptions"
+// CHECK-DWARF-NOT: "-fseh-exceptions"
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mingw-w64-seh-exceptions.cpp b/src/llvm-project/clang/test/CodeGenCXX/mingw-w64-seh-exceptions.cpp
new file mode 100644
index 0000000..f3c3dca
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mingw-w64-seh-exceptions.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 %s -fexceptions -fseh-exceptions -emit-llvm -triple x86_64-w64-windows-gnu -o - | FileCheck %s --check-prefix=X64
+// RUN: %clang_cc1 %s -fexceptions -fdwarf-exceptions -emit-llvm -triple i686-w64-windows-gnu -o - | FileCheck %s --check-prefix=X86
+// RUN: %clang_cc1 %s -fexceptions -emit-llvm -triple i686-w64-windows-gnu -o - | FileCheck %s --check-prefix=X86
+
+extern "C" void foo();
+extern "C" void bar();
+
+struct Cleanup {
+ ~Cleanup() {
+ bar();
+ }
+};
+
+extern "C" void test() {
+ Cleanup x;
+ foo();
+}
+
+// X64: define dso_local void @test()
+// X64-SAME: personality i8* bitcast (i32 (...)* @__gxx_personality_seh0 to i8*)
+// X64: invoke void @foo()
+// X64: landingpad { i8*, i32 }
+
+// X86: define dso_local void @test()
+// X86-SAME: personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+// X86: invoke void @foo()
+// X86: landingpad { i8*, i32 }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/mips-size_t-ptrdiff_t.cpp b/src/llvm-project/clang/test/CodeGenCXX/mips-size_t-ptrdiff_t.cpp
new file mode 100644
index 0000000..5b245a4
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/mips-size_t-ptrdiff_t.cpp
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 -x c++ -emit-llvm -triple=mips-unknown-linux-gnu < %s | FileCheck --check-prefix=O32 %s
+// RUN: %clang_cc1 -x c++ -emit-llvm -triple=mips64-unknown-linux-gnu -target-abi n32 < %s | FileCheck --check-prefix=N32 %s
+// RUN: %clang_cc1 -x c++ -emit-llvm -triple=mips64-unknown-linux-gnu -target-abi n64 < %s | FileCheck --check-prefix=N64 %s
+
+// Test that the size_t is correct for the ABI. It's not sufficient to be the
+// correct size, it must be the same type for correct name mangling.
+
+long *alloc_long() {
+ long *rv = new long; // size_t is implicit in the new operator
+ return rv;
+}
+// O32-LABEL: define i32* @_Z10alloc_longv()
+// O32: call i8* @_Znwj(i32 signext 4)
+
+// N32-LABEL: define i32* @_Z10alloc_longv()
+// N32: call i8* @_Znwj(i32 signext 4)
+
+// N64-LABEL: define i64* @_Z10alloc_longv()
+// N64: call i8* @_Znwm(i64 zeroext 8)
+
+long *alloc_long_array() {
+ long *rv = new long[2];
+ return rv;
+}
+
+// O32-LABEL: define i32* @_Z16alloc_long_arrayv()
+// O32: call i8* @_Znaj(i32 signext 8)
+
+// N32-LABEL: define i32* @_Z16alloc_long_arrayv()
+// N32: call i8* @_Znaj(i32 signext 8)
+
+// N64-LABEL: define i64* @_Z16alloc_long_arrayv()
+// N64: call i8* @_Znam(i64 zeroext 16)
+
+#include <stddef.h>
+
+void size_t_arg(size_t a) {
+}
+
+// O32-LABEL: _Z10size_t_argj
+// N32-LABEL: _Z10size_t_argj
+// N64-LABEL: _Z10size_t_argm
+
+void ptrdiff_t_arg(ptrdiff_t a) {
+}
+
+// O32-LABEL: _Z13ptrdiff_t_argi
+// N32-LABEL: _Z13ptrdiff_t_argi
+// N64-LABEL: _Z13ptrdiff_t_argl
diff --git a/src/llvm-project/clang/test/CodeGenCXX/move-assignment.cpp b/src/llvm-project/clang/test/CodeGenCXX/move-assignment.cpp
new file mode 100644
index 0000000..3653eab
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/move-assignment.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -emit-llvm -std=c++11 -o - %s -triple x86_64-pc-linux-gnu | FileCheck %s
+
+struct A {
+ A &operator=(A&&);
+};
+
+struct B {
+ A a;
+ int i;
+ bool b;
+ char c;
+ long l;
+ float f;
+};
+
+void test1() {
+ B b1, b2;
+ b1 = static_cast<B&&>(b2);
+}
+
+// CHECK-LABEL: define {{.*}} @_ZN1BaSEOS_
+// CHECK: call {{.*}} @_ZN1AaSEOS_
+// CHECK-NOT: store
+// CHECK: call {{.*}}memcpy{{.*}}, i64 24
+// CHECK-NOT: store
+// CHECK: ret
diff --git a/src/llvm-project/clang/test/CodeGenCXX/ms-inline-asm-fields.cpp b/src/llvm-project/clang/test/CodeGenCXX/ms-inline-asm-fields.cpp
new file mode 100644
index 0000000..5ee6acf
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/ms-inline-asm-fields.cpp
@@ -0,0 +1,56 @@
+// REQUIRES: x86-registered-target
+// RUN: %clang_cc1 %s -triple i386-apple-darwin10 -fasm-blocks -emit-llvm -o - | FileCheck %s
+
+struct A {
+ int a1;
+ int a2;
+ struct B {
+ int b1;
+ int b2;
+ } a3;
+};
+
+namespace asdf {
+A a_global;
+}
+
+extern "C" int test_param_field(A p) {
+// CHECK: define i32 @test_param_field(%struct.A* byval align 4 %p)
+// CHECK: getelementptr inbounds %struct.A, %struct.A* %p, i32 0, i32 0
+// CHECK: call i32 asm sideeffect inteldialect "mov eax, $1"
+// CHECK: ret i32
+ __asm mov eax, p.a1
+}
+
+extern "C" int test_namespace_global() {
+// CHECK: define i32 @test_namespace_global()
+// CHECK: call i32 asm sideeffect inteldialect "mov eax, $1", "{{.*}}"(i32* getelementptr inbounds (%struct.A, %struct.A* @_ZN4asdf8a_globalE, i32 0, i32 2, i32 1))
+// CHECK: ret i32
+ __asm mov eax, asdf::a_global.a3.b2
+}
+
+template <bool Signed>
+struct make_storage_type {
+ struct type {
+ struct B {
+ int a;
+ int x;
+ } b;
+ };
+};
+
+template <bool Signed>
+struct msvc_dcas_x86 {
+ typedef typename make_storage_type<Signed>::type storage_type;
+ void store() __asm("PR26001") {
+ storage_type p;
+ __asm mov edx, p.b.x;
+ }
+};
+
+template void msvc_dcas_x86<false>::store();
+// CHECK: define weak_odr void @"\01PR26001"(
+// CHECK: %[[P:.*]] = alloca %"struct.make_storage_type<false>::type", align 4
+// CHECK: %[[B:.*]] = getelementptr inbounds %"struct.make_storage_type<false>::type", %"struct.make_storage_type<false>::type"* %[[P]], i32 0, i32 0
+// CHECK: %[[X:.*]] = getelementptr inbounds %"struct.make_storage_type<false>::type::B", %"struct.make_storage_type<false>::type::B"* %[[B]], i32 0, i32 1
+// CHECK: call void asm sideeffect inteldialect "mov edx, dword ptr $0", "*m,~{edx},~{dirflag},~{fpsr},~{flags}"(i32* %[[X]])
diff --git a/src/llvm-project/clang/test/CodeGenCXX/ms-inline-asm-return.cpp b/src/llvm-project/clang/test/CodeGenCXX/ms-inline-asm-return.cpp
new file mode 100644
index 0000000..4a7165a
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/ms-inline-asm-return.cpp
@@ -0,0 +1,100 @@
+// REQUIRES: x86-registered-target
+// RUN: %clang_cc1 %s -triple i686-pc-windows-msvc -emit-llvm -o - -fasm-blocks | FileCheck %s
+
+// Check that we take EAX or EAX:EDX and return it from these functions for MSVC
+// compatibility.
+
+extern "C" {
+
+long long f_i64() {
+ __asm {
+ mov eax, 1
+ mov edx, 1
+ }
+}
+// CHECK-LABEL: define dso_local i64 @f_i64()
+// CHECK: %[[r:[^ ]*]] = call i64 asm sideeffect inteldialect "mov eax, $$1\0A\09mov edx, $$1", "=A,~{eax},{{.*}}"
+// CHECK: ret i64 %[[r]]
+
+int f_i32() {
+ __asm {
+ mov eax, 1
+ mov edx, 1
+ }
+}
+// CHECK-LABEL: define dso_local i32 @f_i32()
+// CHECK: %[[r:[^ ]*]] = call i32 asm sideeffect inteldialect "mov eax, $$1\0A\09mov edx, $$1", "={eax},~{eax},{{.*}}"
+// CHECK: ret i32 %[[r]]
+
+short f_i16() {
+ __asm {
+ mov eax, 1
+ mov edx, 1
+ }
+}
+// CHECK-LABEL: define dso_local signext i16 @f_i16()
+// CHECK: %[[r:[^ ]*]] = call i32 asm sideeffect inteldialect "mov eax, $$1\0A\09mov edx, $$1", "={eax},~{eax},{{.*}}"
+// CHECK: %[[r_i16:[^ ]*]] = trunc i32 %[[r]] to i16
+// CHECK: ret i16 %[[r_i16]]
+
+char f_i8() {
+ __asm {
+ mov eax, 1
+ mov edx, 1
+ }
+}
+// CHECK-LABEL: define dso_local signext i8 @f_i8()
+// CHECK: %[[r:[^ ]*]] = call i32 asm sideeffect inteldialect "mov eax, $$1\0A\09mov edx, $$1", "={eax},~{eax},{{.*}}"
+// CHECK: %[[r_i8:[^ ]*]] = trunc i32 %[[r]] to i8
+// CHECK: ret i8 %[[r_i8]]
+
+bool f_i1() {
+ __asm {
+ mov eax, 1L
+ mov edx, 1U
+ }
+}
+// CHECK-LABEL: define dso_local zeroext i1 @f_i1()
+// CHECK: %[[r:[^ ]*]] = call i32 asm sideeffect inteldialect "mov eax, $$1\0A\09mov edx, $$1", "={eax},~{eax},{{.*}}"
+// CHECK: %[[r_i8:[^ ]*]] = trunc i32 %[[r]] to i8
+// CHECK: store i8 %[[r_i8]], i8* %{{.*}}
+// CHECK: %[[r_i1:[^ ]*]] = load i1, i1* %{{.*}}
+// CHECK: ret i1 %[[r_i1]]
+
+struct FourChars {
+ char a, b, c, d;
+};
+FourChars f_s4() {
+ __asm {
+ mov eax, 0x01010101
+ }
+}
+// CHECK-LABEL: define dso_local i32 @f_s4()
+// CHECK: %[[r:[^ ]*]] = call i32 asm sideeffect inteldialect "mov eax, $$16843009", "={eax},~{eax},{{.*}}"
+// CHECK: store i32 %[[r]], i32* %{{.*}}
+// CHECK: %[[r_i32:[^ ]*]] = load i32, i32* %{{.*}}
+// CHECK: ret i32 %[[r_i32]]
+
+struct EightChars {
+ char a, b, c, d, e, f, g, h;
+};
+EightChars f_s8() {
+ __asm {
+ mov eax, 01010101h
+ mov edx, 01010101b
+ }
+}
+// CHECK-LABEL: define dso_local i64 @f_s8()
+// CHECK: %[[r:[^ ]*]] = call i64 asm sideeffect inteldialect "mov eax, $$16843009\0A\09mov edx, $$85", "=A,~{eax},{{.*}}"
+// CHECK: store i64 %[[r]], i64* %{{.*}}
+// CHECK: %[[r_i64:[^ ]*]] = load i64, i64* %{{.*}}
+// CHECK: ret i64 %[[r_i64]]
+
+} // extern "C"
+
+int main() {
+ __asm xor eax, eax
+}
+// CHECK-LABEL: define dso_local i32 @main()
+// CHECK: %[[r:[^ ]*]] = call i32 asm sideeffect inteldialect "xor eax, eax", "={eax},{{.*}}"
+// CHECK: ret i32 %[[r]]
diff --git a/src/llvm-project/clang/test/CodeGenCXX/ms-integer-static-data-members-exported.cpp b/src/llvm-project/clang/test/CodeGenCXX/ms-integer-static-data-members-exported.cpp
new file mode 100644
index 0000000..2537361
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/ms-integer-static-data-members-exported.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -emit-llvm -triple=i386-pc-win32 -fms-compatibility %s -o - | FileCheck %s
+
+enum Enum { zero, one, two };
+
+struct __declspec(dllexport) S {
+ // In MS compatibility mode, this counts as a definition.
+ // Since it is exported, it must be emitted even if it's unreferenced.
+ static const short x = 42;
+
+ // This works for enums too.
+ static const Enum y = two;
+
+ struct NonExported {
+ // dllexport is not inherited by this nested class.
+ // Since z is not referenced, it should not be emitted.
+ static const int z = 42;
+ };
+};
+
+// CHECK: @"?x@S@@2FB" = weak_odr dso_local dllexport constant i16 42, comdat, align 2
+// CHECK: @"?y@S@@2W4Enum@@B" = weak_odr dso_local dllexport constant i32 2, comdat, align 4
+// CHECK-NOT: NonExported
diff --git a/src/llvm-project/clang/test/CodeGenCXX/ms-integer-static-data-members.cpp b/src/llvm-project/clang/test/CodeGenCXX/ms-integer-static-data-members.cpp
new file mode 100644
index 0000000..9841435
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/ms-integer-static-data-members.cpp
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -emit-llvm -triple=i386-pc-win32 -fms-compatibility %s -o - | FileCheck %s
+
+struct S {
+ static const int NoInit_Ref;
+ static const int Inline_NotDef_NotRef = 5;
+ static const int Inline_NotDef_Ref = 5;
+ static const int Inline_Def_NotRef = 5;
+ static const int Inline_Def_Ref = 5;
+ static const int OutOfLine_Def_NotRef;
+ static const int OutOfLine_Def_Ref;
+};
+
+const int *foo1() {
+ return &S::NoInit_Ref;
+};
+
+const int *foo2() {
+ return &S::Inline_NotDef_Ref;
+};
+
+const int *foo3() {
+ return &S::Inline_Def_Ref;
+};
+
+const int *foo4() {
+ return &S::OutOfLine_Def_Ref;
+};
+
+const int S::Inline_Def_NotRef;
+const int S::Inline_Def_Ref;
+const int S::OutOfLine_Def_NotRef = 5;
+const int S::OutOfLine_Def_Ref = 5;
+
+
+// No initialization.
+// CHECK-DAG: @"?NoInit_Ref@S@@2HB" = external dso_local constant i32
+
+// Inline initialization, no real definiton, not referenced.
+// CHECK-NOT: @"?Inline_NotDef_NotRef@S@@2HB" = {{.*}} constant i32 5
+
+// Inline initialization, no real definiton, referenced.
+// CHECK-DAG: @"?Inline_NotDef_Ref@S@@2HB" = linkonce_odr dso_local constant i32 5, comdat, align 4
+
+// Inline initialization, real definiton, not referenced.
+// CHECK-NOT: @"?Inline_Def_NotRef@S@@2HB" = dso_local constant i32 5, align 4
+
+// Inline initialization, real definiton, referenced.
+// CHECK-DAG: @"?Inline_Def_Ref@S@@2HB" = linkonce_odr dso_local constant i32 5, comdat, align 4
+
+// Out-of-line initialization.
+// CHECK-DAG: @"?OutOfLine_Def_NotRef@S@@2HB" = dso_local constant i32 5, align 4
+// CHECK-DAG: @"?OutOfLine_Def_Ref@S@@2HB" = dso_local constant i32 5, align 4
diff --git a/src/llvm-project/clang/test/CodeGenCXX/ms-novtable.cpp b/src/llvm-project/clang/test/CodeGenCXX/ms-novtable.cpp
new file mode 100644
index 0000000..db0cf68
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/ms-novtable.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -triple i386-pc-win32 %s -emit-llvm -fms-extensions -fms-compatibility -fno-rtti -o - | FileCheck %s
+
+// CHECK-NOT: @"??_7C@@6B@"
+
+// CHECK-DAG: @"??_7A2@@6B@"
+
+// CHECK-DAG: @"??_7B2@@6B@"
+
+// CHECK-NOT: @"??_7B1@@6B@"
+
+// CHECK-NOT: @"??_7A1@@6B@"
+
+struct __declspec(novtable) A1 {
+ virtual void a();
+} a1;
+struct A2 {
+ virtual void a();
+};
+struct __declspec(novtable) B1 : virtual A1 {} b1;
+struct B2 : virtual A1 {} b2;
+struct __declspec(novtable) C : virtual A2 {} c;
diff --git a/src/llvm-project/clang/test/CodeGenCXX/ms-property.cpp b/src/llvm-project/clang/test/CodeGenCXX/ms-property.cpp
new file mode 100644
index 0000000..4f01528
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/ms-property.cpp
@@ -0,0 +1,113 @@
+// RUN: %clang_cc1 -emit-llvm -triple=x86_64-pc-win32 -fms-compatibility %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fms-compatibility -emit-pch -o %t %s
+// RUN: %clang_cc1 -emit-llvm -triple=x86_64-pc-win32 -fms-compatibility -include-pch %t -verify %s -o - | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+class Test1 {
+private:
+ int x_;
+ double y_;
+
+public:
+ Test1(int x) : x_(x) {}
+ __declspec(property(get = get_x)) int X;
+ int get_x() const { return x_; }
+ static Test1 *GetTest1() { return new Test1(10); }
+};
+
+class S {
+public:
+ __declspec(property(get=GetX,put=PutX)) int x[];
+ int GetX(int i, int j) { return i+j; }
+ void PutX(int i, int j, int k) { j = i = k; }
+};
+
+template <typename T>
+class St {
+public:
+ __declspec(property(get=GetX,put=PutX)) T x[];
+ T GetX(T i, T j) { return i+j; }
+ T GetX() { return 0; }
+ T PutX(T i, T j, T k) { return j = i = k; }
+ __declspec(property(get=GetY,put=PutY)) T y[];
+ char GetY(char i, Test1 j) { return i+j.get_x(); }
+ void PutY(char i, int j, double k) { j = i = k; }
+};
+
+template <typename T>
+void foo(T i, T j) {
+ St<T> bar;
+ Test1 t(i);
+ bar.x[i][j] = bar.x[i][j];
+ bar.y[t.X][j] = bar.x[i][j];
+ bar.x[i][j] = bar.y[bar.x[i][j]][t];
+}
+
+int idx() { return 7; }
+
+// CHECK-LABEL: main
+int main(int argc, char **argv) {
+ Test1 t(argc);
+ S *p1 = 0;
+ St<float> *p2 = 0;
+ // CHECK: call i32 @"?GetX@S@@QEAAHHH@Z"(%class.S* %{{.+}}, i32 223, i32 11)
+ int j = p1->x[223][11];
+ // CHECK: [[J:%.+]] = load i32, i32* %
+ // CHECK-NEXT: call void @"?PutX@S@@QEAAXHHH@Z"(%class.S* %{{.+}}, i32 23, i32 1, i32 [[J]])
+ p1->x[23][1] = j;
+ // CHECK: call float @"?GetX@?$St@M@@QEAAMMM@Z"(%class.St* %{{.+}}, float 2.230000e+02, float 1.100000e+01)
+ float j1 = p2->x[223][11];
+ // CHECK: [[J1:%.+]] = load float, float* %
+ // CHECK-NEXT: [[CALL:%.+]] = call float @"?PutX@?$St@M@@QEAAMMMM@Z"(%class.St* %{{.+}}, float 2.300000e+01, float 1.000000e+00, float [[J1]])
+ // CHECK-NEXT: [[CONV:%.+]] = fptosi float [[CALL]] to i32
+ // CHECK-NEXT: store i32 [[CONV]], i32*
+ argc = p2->x[23][1] = j1;
+ // CHECK: [[IDX:%.+]] = call i32 @"?idx@@YAHXZ"()
+ // CHECK-NEXT: [[CONV:%.+]] = sitofp i32 [[IDX]] to float
+ // CHECK-NEXT: [[GET:%.+]] = call float @"?GetX@?$St@M@@QEAAMMM@Z"(%class.St* %{{.+}}, float [[CONV]], float 1.000000e+00)
+ // CHECK-NEXT: [[INC:%.+]] = fadd float [[GET]], 1.000000e+00
+ // CHECK-NEXT: [[CONV:%.+]] = sitofp i32 [[IDX]] to float
+ // CHECK-NEXT: call float @"?PutX@?$St@M@@QEAAMMMM@Z"(%class.St* %{{.+}}, float [[CONV]], float 1.000000e+00, float [[INC]])
+ ++p2->x[idx()][1];
+ // CHECK: call void @"??$foo@H@@YAXHH@Z"(i32 %{{.+}}, i32 %{{.+}})
+ foo(argc, (int)argv[0][0]);
+ // CHECK: [[P2:%.+]] = load %class.St*, %class.St** %
+ // CHECK: [[P1:%.+]] = load %class.S*, %class.S** %
+ // CHECK: [[P1_X_22_33:%.+]] = call i32 @"?GetX@S@@QEAAHHH@Z"(%class.S* [[P1]], i32 22, i32 33)
+ // CHECK: [[CAST:%.+]] = sitofp i32 [[P1_X_22_33]] to double
+ // CHECK: [[ARGC:%.+]] = load i32, i32* %
+ // CHECK: [[T_X:%.+]] = call i32 @"?get_x@Test1@@QEBAHXZ"(%class.Test1* %{{.+}})
+ // CHECK: [[CAST2:%.+]] = trunc i32 [[T_X]] to i8
+ // CHECK: call void @"?PutY@?$St@M@@QEAAXDHN@Z"(%class.St* [[P2]], i8 [[CAST2]], i32 [[ARGC]], double [[CAST]])
+ p2->y[t.X][argc] = p1->x[22][33];
+ // CHECK: [[P2_1:%.+]] = load %class.St*, %class.St**
+ // CHECK: [[P2_2:%.+]] = load %class.St*, %class.St**
+ // CHECK: [[P1:%.+]] = load %class.S*, %class.S**
+ // CHECK: [[ARGC:%.+]] = load i32, i32* %
+ // CHECK: [[P1_X_ARGC_0:%.+]] = call i32 @"?GetX@S@@QEAAHHH@Z"(%class.S* [[P1]], i32 [[ARGC]], i32 0)
+ // CHECK: [[CAST:%.+]] = trunc i32 [[P1_X_ARGC_0]] to i8
+ // CHECK: [[P2_Y_p1_X_ARGC_0_T:%.+]] = call i8 @"?GetY@?$St@M@@QEAADDVTest1@@@Z"(%class.St* [[P2_2]], i8 [[CAST]], %class.Test1* %{{.+}})
+ // CHECK: [[CAST:%.+]] = sitofp i8 [[P2_Y_p1_X_ARGC_0_T]] to float
+ // CHECK: [[J:%.+]] = load i32, i32* %
+ // CHECK: [[CAST1:%.+]] = sitofp i32 [[J]] to float
+ // CHECK: [[J:%.+]] = load i32, i32* %
+ // CHECK: [[CAST2:%.+]] = sitofp i32 [[J]] to float
+ // CHECK: call float @"?PutX@?$St@M@@QEAAMMMM@Z"(%class.St* [[P2_1]], float [[CAST2]], float [[CAST1]], float [[CAST]])
+ p2->x[j][j] = p2->y[p1->x[argc][0]][t];
+ // CHECK: [[CALL:%.+]] = call %class.Test1* @"?GetTest1@Test1@@SAPEAV1@XZ"()
+ // CHECK-NEXT: call i32 @"?get_x@Test1@@QEBAHXZ"(%class.Test1* [[CALL]])
+ return Test1::GetTest1()->X;
+}
+
+// CHECK: define linkonce_odr dso_local void @"??$foo@H@@YAXHH@Z"(i32 %{{.+}}, i32 %{{.+}})
+// CHECK: call i32 @"?GetX@?$St@H@@QEAAHHH@Z"(%class.St{{.+}}* [[BAR:%.+]], i32 %{{.+}} i32 %{{.+}})
+// CHECK: call i32 @"?PutX@?$St@H@@QEAAHHHH@Z"(%class.St{{.+}}* [[BAR]], i32 %{{.+}}, i32 %{{.+}}, i32 %{{.+}})
+// CHECK: call i32 @"?GetX@?$St@H@@QEAAHHH@Z"(%class.St{{.+}}* [[BAR]], i32 %{{.+}} i32 %{{.+}})
+// CHECK: call void @"?PutY@?$St@H@@QEAAXDHN@Z"(%class.St{{.+}}* [[BAR]], i8 %{{.+}}, i32 %{{.+}}, double %{{.+}}
+// CHECK: call i32 @"?GetX@?$St@H@@QEAAHHH@Z"(%class.St{{.+}}* [[BAR]], i32 %{{.+}} i32 %{{.+}})
+// CHECK: call i8 @"?GetY@?$St@H@@QEAADDVTest1@@@Z"(%class.St{{.+}}* [[BAR]], i8 %{{.+}}, %class.Test1* %{{.+}})
+// CHECK: call i32 @"?PutX@?$St@H@@QEAAHHHH@Z"(%class.St{{.+}}* [[BAR]], i32 %{{.+}}, i32 %{{.+}}, i32 %{{.+}})
+#endif //HEADER
diff --git a/src/llvm-project/clang/test/CodeGenCXX/ms-thread_local.cpp b/src/llvm-project/clang/test/CodeGenCXX/ms-thread_local.cpp
new file mode 100644
index 0000000..76eba52
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/ms-thread_local.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 %s -std=c++1y -triple=i686-pc-win32 -emit-llvm -o - | FileCheck %s
+
+struct A {
+ A();
+ ~A();
+};
+
+// CHECK-DAG: $"??$a@X@@3UA@@A" = comdat any
+// CHECK-DAG: @"??$a@X@@3UA@@A" = linkonce_odr dso_local thread_local global %struct.A zeroinitializer, comdat, align 1
+// CHECK-DAG: @"??__E?$a@X@@YAXXZ$initializer$" = internal constant void ()* @"??__E?$a@X@@YAXXZ", section ".CRT$XDU", comdat($"??$a@X@@3UA@@A")
+template <typename T>
+thread_local A a = A();
+
+// CHECK-DAG: @"?b@@3UA@@A" = dso_local thread_local global %struct.A zeroinitializer, align 1
+// CHECK-DAG: @"__tls_init$initializer$" = internal constant void ()* @__tls_init, section ".CRT$XDU"
+thread_local A b;
+
+// CHECK-LABEL: define internal void @__tls_init()
+// CHECK: call void @"??__Eb@@YAXXZ"
+
+thread_local A &c = b;
+thread_local A &d = c;
+
+A f() {
+ (void)a<void>;
+ (void)b;
+ return c;
+}
+
+// CHECK: !llvm.linker.options = !{![[dyn_tls_init:[0-9]+]]}
+// CHECK: ![[dyn_tls_init]] = !{!"/include:___dyn_tls_init@12"}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/ms-thunks-unprototyped-return.cpp b/src/llvm-project/clang/test/CodeGenCXX/ms-thunks-unprototyped-return.cpp
new file mode 100644
index 0000000..ef39fd7
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/ms-thunks-unprototyped-return.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fno-rtti-data -triple x86_64-windows-msvc -emit-llvm-only %s -verify
+
+// Verify that we error out on this return adjusting thunk that we can't emit.
+
+struct Incomplete;
+
+struct A {
+ virtual A * clone(Incomplete p) = 0;
+};
+struct B : virtual A {
+ // expected-error@+1 2 {{cannot compile this return-adjusting thunk with incomplete parameter type yet}}
+ B * clone(Incomplete p) override;
+};
+struct C : B { int c; };
+C c;
diff --git a/src/llvm-project/clang/test/CodeGenCXX/ms-thunks-unprototyped.cpp b/src/llvm-project/clang/test/CodeGenCXX/ms-thunks-unprototyped.cpp
new file mode 100644
index 0000000..0a232b9
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/ms-thunks-unprototyped.cpp
@@ -0,0 +1,73 @@
+// RUN: %clang_cc1 -fno-rtti-data -triple x86_64-windows-msvc -emit-llvm %s -o - | FileCheck %s
+
+// In this example, C does not override B::foo, but it needs to emit a thunk to
+// adjust for the relative difference of position between A-in-B and A-in-C.
+
+struct Incomplete;
+template <typename T>
+struct DoNotInstantiate {
+ typename T::does_not_exist field;
+};
+template <typename T>
+struct InstantiateLater;
+
+struct A {
+ virtual void foo(Incomplete p) = 0;
+ virtual void bar(DoNotInstantiate<int> p) = 0;
+ virtual int baz(InstantiateLater<int> p) = 0;
+};
+struct B : virtual A {
+ void foo(Incomplete p) override;
+ void bar(DoNotInstantiate<int> p) override;
+ inline int baz(InstantiateLater<int> p) override;
+};
+struct C : B { int c; };
+C c;
+
+// Do the same thing, but with an incomplete return type.
+struct B1 { virtual DoNotInstantiate<void> f() = 0; };
+struct B2 { virtual DoNotInstantiate<void> f() = 0; };
+struct S : B1, B2 { DoNotInstantiate<void> f() override; };
+S s;
+
+// CHECK: @"??_7S@@6BB2@@@" = linkonce_odr unnamed_addr constant
+// CHECK-SAME: void (%struct.S*, ...)* @"?f@S@@W7EAA?AU?$DoNotInstantiate@X@@XZ"
+
+// CHECK: @"??_7C@@6B@" = linkonce_odr unnamed_addr constant
+// CHECK-SAME: void (%struct.B*, ...)* @"?foo@B@@W7EAAXUIncomplete@@@Z"
+// CHECK-SAME: void (%struct.B*, ...)* @"?bar@B@@W7EAAXU?$DoNotInstantiate@H@@@Z"
+// CHECK-SAME: i32 (i8*, i32)* @"?baz@B@@W7EAAHU?$InstantiateLater@H@@@Z"
+
+
+// CHECK-LABEL: define linkonce_odr dso_local void @"?f@S@@W7EAA?AU?$DoNotInstantiate@X@@XZ"(%struct.S* %this, ...)
+// CHECK: %[[THIS_ADJ_i8:[^ ]*]] = getelementptr i8, i8* {{.*}}, i32 -8
+// CHECK: %[[THIS_ADJ:[^ ]*]] = bitcast i8* %[[THIS_ADJ_i8]] to %struct.S*
+// CHECK: musttail call void (%struct.S*, ...) {{.*}}@"?f@S@@UEAA?AU?$DoNotInstantiate@X@@XZ"
+// CHECK-SAME: (%struct.S* %[[THIS_ADJ]], ...)
+// CHECK: ret void
+
+// The thunks should have a -8 adjustment.
+
+// CHECK-LABEL: define linkonce_odr dso_local void @"?foo@B@@W7EAAXUIncomplete@@@Z"(%struct.B* %this, ...)
+// CHECK: %[[THIS_ADJ_i8:[^ ]*]] = getelementptr i8, i8* {{.*}}, i32 -8
+// CHECK: %[[THIS_ADJ:[^ ]*]] = bitcast i8* %[[THIS_ADJ_i8]] to %struct.B*
+// CHECK: musttail call void (%struct.B*, ...) {{.*}}@"?foo@B@@UEAAXUIncomplete@@@Z"
+// CHECK-SAME: (%struct.B* %[[THIS_ADJ]], ...)
+// CHECK-NEXT: ret void
+
+// CHECK-LABEL: define linkonce_odr dso_local void @"?bar@B@@W7EAAXU?$DoNotInstantiate@H@@@Z"(%struct.B* %this, ...)
+// CHECK: %[[THIS_ADJ_i8:[^ ]*]] = getelementptr i8, i8* {{.*}}, i32 -8
+// CHECK: %[[THIS_ADJ:[^ ]*]] = bitcast i8* %[[THIS_ADJ_i8]] to %struct.B*
+// CHECK: musttail call void (%struct.B*, ...) {{.*}}@"?bar@B@@UEAAXU?$DoNotInstantiate@H@@@Z"
+// CHECK-SAME: (%struct.B* %[[THIS_ADJ]], ...)
+// CHECK-NEXT: ret void
+
+// If we complete the definition later, things work out.
+template <typename T> struct InstantiateLater { T x; };
+inline int B::baz(InstantiateLater<int> p) { return p.x; }
+
+// CHECK-LABEL: define linkonce_odr dso_local i32 @"?baz@B@@W7EAAHU?$InstantiateLater@H@@@Z"(i8* %this.coerce, i32 %p.coerce)
+// CHECK: = getelementptr i8, i8* {{.*}}, i32 -8
+// CHECK: tail call i32 @"?baz@B@@UEAAHU?$InstantiateLater@H@@@Z"(i8* {{[^,]*}}, i32 {{.*}})
+
+// CHECK-LABEL: define linkonce_odr dso_local i32 @"?baz@B@@UEAAHU?$InstantiateLater@H@@@Z"(i8* %this.coerce, i32 %p.coerce)
diff --git a/src/llvm-project/clang/test/CodeGenCXX/ms_struct.cpp b/src/llvm-project/clang/test/CodeGenCXX/ms_struct.cpp
new file mode 100644
index 0000000..32307ba
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/ms_struct.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s
+
+// rdar://20636558
+
+#pragma GCC diagnostic ignored "-Wincompatible-ms-struct"
+#define ATTR __attribute__((__ms_struct__))
+
+struct ATTR VBase {
+ virtual void foo() = 0;
+};
+
+struct ATTR Base : virtual VBase {
+ virtual void bar() = 0;
+};
+
+struct ATTR Derived : Base {
+ Derived();
+ void foo();
+ void bar();
+ int value;
+};
+
+// CHECK: [[DERIVED:%.*]] = type <{ [[BASE:%.*]], i32, [4 x i8] }>
+// CHECK: [[BASE]] = type { [[VBASE:%.*]] }
+// CHECK: [[VBASE]] = type { i32 (...)** }
+
+// CHECK: define void @_ZN7DerivedC2Ev
+// CHECK: [[SELF:%.*]] = load [[DERIVED]]*
+// CHECK: [[T0:%.*]] = bitcast [[DERIVED]]* [[SELF]] to [[BASE]]*
+// CHECK: call void @_ZN4BaseC2Ev([[BASE]]* [[T0]], i8**
+// CHECK: [[T0:%.*]] = getelementptr inbounds {{.*}} [[SELF]], i32 0, i32 1
+// CHECK: store i32 20, i32* [[T0]],
+Derived::Derived() : value(20) {}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/ms_wide_predefined_expr.cpp b/src/llvm-project/clang/test/CodeGenCXX/ms_wide_predefined_expr.cpp
new file mode 100644
index 0000000..bdfd1cd
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/ms_wide_predefined_expr.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 %s -fms-extensions -triple i686-pc-win32 -emit-llvm -o - | FileCheck %s
+
+// CHECK: @"??_C@_19DPFBEKIN@?$AAf?$AAu?$AAn?$AAc?$AA?$AA@" = linkonce_odr dso_local unnamed_addr constant [5 x i16] [i16 102, i16 117, i16 110, i16 99, i16 0], comdat, align 2
+
+void wprint(const wchar_t*);
+
+#define __STR2WSTR(str) L##str
+#define _STR2WSTR(str) __STR2WSTR(str)
+#define STR2WSTR(str) _STR2WSTR(str)
+
+void func() {
+ wprint(STR2WSTR(__FUNCTION__));
+}
+
+int main() {
+ func();
+
+ return 0;
+}
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/msabi-blocks.cpp b/src/llvm-project/clang/test/CodeGenCXX/msabi-blocks.cpp
new file mode 100644
index 0000000..02d0958
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/msabi-blocks.cpp
@@ -0,0 +1,113 @@
+// RUN: %clang_cc1 -triple i686-unknown-windows-msvc -std=c++11 -fblocks -S -o - -emit-llvm %s | FileCheck %s -check-prefix CHECK-X86
+// RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -std=c++11 -fblocks -S -o - -emit-llvm %s | FileCheck %s -check-prefix CHECK-X64
+
+extern int e(void);
+
+void (^b)() = ^{
+ static int i = 0;
+};
+
+// CHECK-X86-DAG: @"?i@?1??_block_invoke@@YAXPAU__block_literal@@@Z@4HA" ={{.*}} global i32 0
+// CHECK-X64-DAG: @"?i@?1??_block_invoke@@YAXPEAU__block_literal@@@Z@4HA" ={{.*}} global i32 0
+
+void f(void) {
+ static int i = 0;
+ ^{ static int i = e(); }();
+
+// CHECK-X86-DAG: @"?i@?1??_block_invoke_1@@YAXPAU__block_literal_1@@@Z?1??f@@YAXXZ@4HA" ={{.*}} global i32 0
+// CHECK-X64-DAG: @"?i@?1??_block_invoke_1@@YAXPEAU__block_literal_1@@@Z?1??f@@YAXXZ@4HA" ={{.*}} global i32 0
+
+ ^{ static int i = e(); }();
+
+// CHECK-X86-DAG: @"?i@?1??_block_invoke_2@@YAXPAU__block_literal_2@@@Z?1??f@@YAXXZ@4HA" ={{.*}} global i32 0
+// CHECK-X64-DAG: @"?i@?1??_block_invoke_2@@YAXPEAU__block_literal_2@@@Z?1??f@@YAXXZ@4HA" ={{.*}} global i32 0
+
+ ^{ ^{ static int i = e(); }(); }();
+
+// CHECK-X86-DAG: @"?i@?1??_block_invoke_3@@YAXPAU__block_literal_3@@@Z?1??_block_invoke_4@@YAXPAU__block_literal_4@@@Z?1??f@@YAXXZ@4HA" ={{.*}} global i32 0
+// CHECK-X64-DAG: @"?i@?1??_block_invoke_3@@YAXPEAU__block_literal_3@@@Z?1??_block_invoke_4@@YAXPEAU__block_literal_4@@@Z?1??f@@YAXXZ@4HA" ={{.*}} global i32 0
+}
+
+
+template <typename>
+void g(void) {
+ ^{ static int i = e(); }();
+}
+
+template void g<char>(void);
+
+// CHECK-X86-DAG: @"?i@?2??_block_invoke_1@@YAXPAU__block_literal_1@@@Z?2???$g@D@@YAXXZ@4HA" ={{.*}} global i32 0
+// CHECK-X64-DAG: @"?i@?2??_block_invoke_1@@YAXPEAU__block_literal_1@@@Z?2???$g@D@@YAXXZ@4HA" ={{.*}} global i32 0
+
+template void g<int>(void);
+
+// CHECK-X86-DAG: @"?i@?2??_block_invoke_1@@YAXPAU__block_literal_1@@@Z?2???$g@H@@YAXXZ@4HA" ={{.*}} global i32 0
+// CHECK-X64-DAG: @"?i@?2??_block_invoke_1@@YAXPEAU__block_literal_1@@@Z?2???$g@H@@YAXXZ@4HA" ={{.*}} global i32 0
+
+inline void h(void) {
+ ^{ static int i = e(); }();
+}
+
+// CHECK-X86-DAG: @"?i@?2??_block_invoke_1@@YAXPAU__block_literal_1@@@Z?2??h@@YAXXZ@4HA" ={{.*}} global i32 0
+// CHECK-X64-DAG: @"?i@?2??_block_invoke_1@@YAXPEAU__block_literal_1@@@Z?2??h@@YAXXZ@4HA" ={{.*}} global i32 0
+
+struct s {
+ int i = ^{ static int i = e(); return ++i; }();
+
+// CHECK-X86-DAG: @"?i@?0??_block_invoke_1@0s@@YAXPAU__block_literal_1@@@Z@4HA" ={{.*}} global i32 0
+// CHECK-X64-DAG: @"?i@?0??_block_invoke_1@0s@@YAXPEAU__block_literal_1@@@Z@4HA" ={{.*}} global i32 0
+
+ int j = ^{ static int i = e(); return ++i; }();
+
+// CHECK-X86-DAG: @"?i@?0??_block_invoke_1@j@s@@YAXPAU__block_literal_1@@@Z@4HA" ={{.*}} global i32 0
+// CHECK-X64-DAG: @"?i@?0??_block_invoke_1@j@s@@YAXPEAU__block_literal_1@@@Z@4HA" ={{.*}} global i32 0
+
+ void m(int i = ^{ static int i = e(); return ++i; }(),
+ int j = ^{ static int i = e(); return ++i; }()) {}
+
+// CHECK-X86-DAG: @"?i@?0??_block_invoke_1_1@@YAXPAU__block_literal_1_1@@@Z?0??m@s@@QAEXHH@Z@4HA" ={{.*}} global i32 0
+// CHECK-X86-DAG: @"?i@?0??_block_invoke_1_2@@YAXPAU__block_literal_1_2@@@Z?0??m@s@@QAEXHH@Z@4HA" ={{.*}} global i32 0
+// CHECK-X64-DAG: @"?i@?0??_block_invoke_1_1@@YAXPEAU__block_literal_1_1@@@Z?0??m@s@@QEAAXHH@Z@4HA" ={{.*}} global i32 0
+// CHECK-X64-DAG: @"?i@?0??_block_invoke_1_2@@YAXPEAU__block_literal_1_2@@@Z?0??m@s@@QEAAXHH@Z@4HA" ={{.*}} global i32 0
+
+ void n(int = ^{ static int i = e(); return ++i; }(),
+ int = ^{ static int i = e(); return ++i; }()) {}
+
+// CHECK-X86-DAG: @"?i@?0??_block_invoke_1_1@@YAXPAU__block_literal_1_1@@@Z?0??n@s@@QAEXHH@Z@4HA" ={{.*}} global i32 0
+// CHECK-X86-DAG: @"?i@?0??_block_invoke_1_2@@YAXPAU__block_literal_1_2@@@Z?0??n@s@@QAEXHH@Z@4HA" ={{.*}} global i32 0
+// CHECK-X64-DAG: @"?i@?0??_block_invoke_1_1@@YAXPEAU__block_literal_1_1@@@Z?0??n@s@@QEAAXHH@Z@4HA" ={{.*}} global i32 0
+// CHECK-X64-DAG: @"?i@?0??_block_invoke_1_2@@YAXPEAU__block_literal_1_2@@@Z?0??n@s@@QEAAXHH@Z@4HA" ={{.*}} global i32 0
+
+};
+
+struct t {
+ struct u {
+ int i = ^{ static int i = e(); return ++i; }();
+
+// CHECK-X86-DAG: @"?i@?0??_block_invoke_1@0u@t@@YAXPAU__block_literal_1@@@Z@4HA" ={{.*}} global i32 0
+// CHECK-X64-DAG: @"?i@?0??_block_invoke_1@0u@t@@YAXPEAU__block_literal_1@@@Z@4HA" ={{.*}} global i32 0
+
+ };
+};
+
+void j(void) {
+ h();
+ struct s s;
+ s.m();
+ s.n();
+ struct t::u t;
+}
+
+#if 0
+template <typename T>
+struct v {
+ static T i;
+};
+
+template <typename T>
+T v<T>::i = ^{ static T i = T(); return i; }();
+
+template class v<char>;
+template class v<int>;
+#endif
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/msabi-swiftcall-cc.cpp b/src/llvm-project/clang/test/CodeGenCXX/msabi-swiftcall-cc.cpp
new file mode 100644
index 0000000..3cc90a8
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/msabi-swiftcall-cc.cpp
@@ -0,0 +1,67 @@
+// RUN: %clang_cc1 -triple i686-unknown-windows-msvc -fdeclspec -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -fdeclspec -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-64
+
+void __attribute__((__swiftcall__)) f() {}
+// CHECK-DAG: @"?f@@YSXXZ"
+// CHECK-64-DAG: @"?f@@YSXXZ"
+
+void (__attribute__((__swiftcall__)) *p)();
+// CHECK-DAG: @"?p@@3P6SXXZA"
+// CHECK-64-DAG: @"?p@@3P6SXXZEA
+
+namespace {
+void __attribute__((__swiftcall__)) __attribute__((__used__)) f() { }
+}
+// CHECK-DAG: @"?f@?A0x{{[^@]*}}@@YSXXZ"
+// CHECK-64-DAG: @"?f@?A0x{{[^@]*}}@@YSXXZ"
+
+namespace n {
+void __attribute__((__swiftcall__)) f() {}
+}
+// CHECK-DAG: @"?f@n@@YSXXZ"
+// CHECK-64-DAG: @"?f@n@@YSXXZ"
+
+struct __declspec(dllexport) S {
+ S(const S &) = delete;
+ S & operator=(const S &) = delete;
+ void __attribute__((__swiftcall__)) m() { }
+};
+// CHECK-DAG: @"?m@S@@QASXXZ"
+// CHECK-64-DAG: @"?m@S@@QEASXXZ"
+
+void f(void (__attribute__((__swiftcall__))())) {}
+// CHECK-DAG: @"?f@@YAXP6SXXZ@Z"
+// CHECK-64-DAG: @"?f@@YAXP6SXXZ@Z"
+
+void __attribute__((__preserve_most__)) g() {}
+// CHECK-DAG: @"?g@@YUXXZ"
+// CHECK-64-DAG: @"?g@@YUXXZ"
+
+void (__attribute__((__preserve_most__)) *q)();
+// CHECK-DAG: @"?q@@3P6UXXZA"
+// CHECK-64-DAG: @"?q@@3P6UXXZEA"
+
+namespace {
+void __attribute__((__preserve_most__)) __attribute__((__used__)) g() {}
+}
+// CHECK-DAG: @"?g@?A0x{{[^@]*}}@@YUXXZ"
+// CHECK-64-DAG: @"?g@?A0x{{[^@]*}}@@YUXXZ"
+
+namespace n {
+void __attribute__((__preserve_most__)) g() {}
+}
+// CHECK-DAG: @"?g@n@@YUXXZ"
+// CHECK-64-DAG: @"?g@n@@YUXXZ"
+
+struct __declspec(dllexport) T {
+ T(const T &) = delete;
+ T & operator=(const T &) = delete;
+ void __attribute__((__preserve_most__)) m() {}
+};
+// CHECK-DAG: @"?m@T@@QAUXXZ"
+// CHECK-64-DAG: @"?m@T@@QEAUXXZ"
+
+void g(void (__attribute__((__preserve_most__))())) {}
+// CHECK-DAG: @"?g@@YAXP6UXXZ@Z"
+// CHECK-64-DAG: @"?g@@YAXP6UXXZ@Z"
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/multi-dim-operator-new.cpp b/src/llvm-project/clang/test/CodeGenCXX/multi-dim-operator-new.cpp
new file mode 100644
index 0000000..0dfcffb
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/multi-dim-operator-new.cpp
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 %s -triple x86_64-unknown-unknown -emit-llvm -o - | FileCheck %s
+// PR6641
+
+extern "C" int printf(const char *, ...);
+
+struct Foo {
+ Foo() : iFoo (2) {
+ printf("%p\n", this);
+ }
+ int iFoo;
+};
+
+
+typedef Foo (*T)[3][4];
+
+T bar() {
+ return new Foo[2][3][4];
+}
+
+T bug(int i) {
+ return new Foo[i][3][4];
+}
+
+void pr(T a) {
+ for (int i = 0; i < 3; i++)
+ for (int j = 0; j < 4; j++)
+ printf("%p\n", a[i][j]);
+}
+
+Foo *test() {
+ return new Foo[5];
+}
+
+int main() {
+ T f = bar();
+ pr(f);
+ f = bug(3);
+ pr(f);
+
+ Foo * g = test();
+ for (int i = 0; i < 5; i++)
+ printf("%d\n", g[i].iFoo);
+ return 0;
+}
+
+// CHECK: call i8* @_Znam
+// CHECK: call i8* @_Znam
+// CHECK: call i8* @_Znam
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/naked.cpp b/src/llvm-project/clang/test/CodeGenCXX/naked.cpp
new file mode 100644
index 0000000..c6fe133
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/naked.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-windows -emit-llvm %s -o - | FileCheck %s
+
+class TestNaked {
+public:
+ void NakedFunction();
+};
+
+__attribute__((naked)) void TestNaked::NakedFunction() {
+ // CHECK-LABEL: define {{(dso_local )?}}{{(x86_thiscallcc )?}}void @
+ // CHECK: call void asm sideeffect
+ asm("");
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/namespace-aliases.cpp b/src/llvm-project/clang/test/CodeGenCXX/namespace-aliases.cpp
new file mode 100644
index 0000000..8624eb7
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/namespace-aliases.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -emit-llvm-only %s
+namespace A { }
+namespace B = A;
+
+namespace b {}
+
+void foo() {
+ namespace a = b;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/nested-base-member-access.cpp b/src/llvm-project/clang/test/CodeGenCXX/nested-base-member-access.cpp
new file mode 100644
index 0000000..f1c7dd9
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/nested-base-member-access.cpp
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 %s -emit-llvm -o %t
+
+extern "C" int printf(...);
+
+struct M {
+ M(int i){ iM = i; }
+ int iM;
+ void MPR() { printf("iM = %d\n", iM); }
+
+};
+
+struct Q {
+ Q(int i){ iQ = i; }
+ int iQ;
+ void QPR() { printf("iQ = %d\n", iQ); }
+};
+
+struct IQ {
+ IQ(int i) { iIQ = i; }
+ void IQPR() { printf("iIQ = %d\n", iIQ); }
+ int iIQ;
+};
+
+struct L : IQ {
+ L(int i) : IQ(i+100) { iL = i; }
+ int iL;
+};
+
+struct P : Q, L {
+ P(int i) : Q(i+100), L(i+200) { iP = i; }
+ int iP;
+ void PPR() { printf("iP = %d\n", iP); }
+};
+
+
+struct N : M,P {
+ N() : M(100), P(200) {}
+ void PR() {
+ this->MPR(); this->PPR(); this->QPR();
+ IQPR();
+ printf("iM = %d\n", iM);
+ printf("iP = %d\n", iP);
+ printf("iQ = %d\n", iQ);
+ printf("iL = %d\n", iL);
+ printf("iIQ = %d\n", iIQ);
+ }
+};
+
+int main() {
+ N n1;
+ n1.PR();
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/new-alias.cpp b/src/llvm-project/clang/test/CodeGenCXX/new-alias.cpp
new file mode 100644
index 0000000..b21638a
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/new-alias.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -emit-llvm -triple x86_64-linux-gnu -std=c++11 -o - %s | FileCheck %s
+
+using size_t = decltype(sizeof(0));
+
+extern "C" char *something(long long x) {
+}
+
+// CHECK: @_Znwm = alias i8* (i64), i8* (i64)* @something
+void *operator new(size_t) __attribute__((alias("something")));
+
+// PR16715: don't assert here.
+// CHECK: call i8* @_Znwm(i64 4){{$}}
+int *pr16715 = new int;
diff --git a/src/llvm-project/clang/test/CodeGenCXX/new-array-init-exceptions.cpp b/src/llvm-project/clang/test/CodeGenCXX/new-array-init-exceptions.cpp
new file mode 100644
index 0000000..5cfb757
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/new-array-init-exceptions.cpp
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -std=c++11 -triple i386-unknown-unknown -fexceptions -fcxx-exceptions %s -emit-llvm -o - | FileCheck %s
+// REQUIRES: asserts
+
+struct Throws {
+ Throws(int);
+ Throws();
+ ~Throws();
+};
+
+// CHECK-LABEL: define void @_Z7cleanupi
+void cleanup(int n) {
+ // CHECK: invoke void @_ZN6ThrowsC1Ei
+ // CHECK-NEXT: to label %{{[^ ]+}} unwind label %[[LPAD:[^ ]+]]
+ // CHECK: invoke void @_ZN6ThrowsC1Ei
+ // CHECK-NEXT: to label %{{[^ ]+}} unwind label %[[LPAD]]
+ // CHECK: invoke void @_ZN6ThrowsC1Ei
+ // CHECK-NEXT: to label %{{[^ ]+}} unwind label %[[LPAD]]
+ // CHECK: invoke void @_ZN6ThrowsC1Ev
+ // CHECK-NEXT: to label %{{[^ ]+}} unwind label %[[LPAD]]
+ new Throws[n] { 1, 2, 3 };
+ // CHECK: [[LPAD]]:
+ // CHECK-NEXT: landingpad
+ // CHECK: call void @_ZN6ThrowsD1Ev
+ // CHECK: call void @_ZdaPv
+}
+
+
+// CHECK-LABEL: define void @_Z7cleanupv
+void cleanup() {
+ // CHECK: invoke void @_ZN6ThrowsC1Ei
+ // CHECK-NEXT: to label %{{[^ ]+}} unwind label %[[LPAD2:[^ ]+]]
+ // CHECK: invoke void @_ZN6ThrowsC1Ei
+ // CHECK-NEXT: to label %{{[^ ]+}} unwind label %[[LPAD2]]
+ // CHECK: invoke void @_ZN6ThrowsC1Ei
+ // CHECK-NEXT: to label %{{[^ ]+}} unwind label %[[LPAD2]]
+ new Throws[3] { 1, 2, 3 };
+ // CHECK: [[LPAD2]]:
+ // CHECK-NEXT: landingpad
+ // CHECK: call void @_ZN6ThrowsD1Ev
+ // CHECK: call void @_ZdaPv
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/new-array-init.cpp b/src/llvm-project/clang/test/CodeGenCXX/new-array-init.cpp
new file mode 100644
index 0000000..90cd600
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/new-array-init.cpp
@@ -0,0 +1,125 @@
+// RUN: %clang_cc1 -std=c++11 -triple i386-unknown-unknown %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -triple i386-unknown-unknown %s -emit-llvm -fsanitize=signed-integer-overflow -o - | FileCheck --check-prefix=SIO %s
+
+// CHECK: @[[ABC4:.*]] = {{.*}} constant [4 x i8] c"abc\00"
+// CHECK: @[[ABC15:.*]] = {{.*}} constant [15 x i8] c"abc\00\00\00\00
+
+// CHECK-LABEL: define void @_Z2fni
+void fn(int n) {
+ // CHECK: icmp ult i{{32|64}} %{{[^ ]+}}, 3
+ // CHECK: store i32 1
+ // CHECK: store i32 2
+ // CHECK: store i32 3
+ // CHECK: sub {{.*}}, 12
+ // CHECK: call void @llvm.memset
+ new int[n] { 1, 2, 3 };
+}
+
+// CHECK-LABEL: define void @_Z11const_exactv
+void const_exact() {
+ // CHECK-NOT: icmp ult i{{32|64}} %{{[^ ]+}}, 3
+ // CHECK-NOT: icmp eq i32*
+ new int[3] { 1, 2, 3 };
+}
+
+// CHECK-LABEL: define void @_Z16const_sufficientv
+void const_sufficient() {
+ // CHECK-NOT: icmp ult i{{32|64}} %{{[^ ]+}}, 3
+ new int[4] { 1, 2, 3 };
+ // CHECK: ret void
+}
+
+// CHECK-LABEL: define void @_Z22check_array_value_initv
+void check_array_value_init() {
+ struct S;
+ new (int S::*[3][4][5]) ();
+
+ // CHECK: call i8* @_Zna{{.}}(i{{32 240|64 480}})
+ // CHECK: getelementptr inbounds i{{32|64}}, i{{32|64}}* {{.*}}, i{{32|64}} 60
+
+ // CHECK: phi
+ // CHECK: store i{{32|64}} -1,
+ // CHECK: getelementptr inbounds i{{32|64}}, i{{32|64}}* {{.*}}, i{{32|64}} 1
+ // CHECK: icmp eq
+ // CHECK: br i1
+}
+
+// CHECK-LABEL: define void @_Z15string_nonconsti
+void string_nonconst(int n) {
+ // CHECK: icmp slt i{{32|64}} %{{[^ ]+}}, 4
+ // FIXME: Conditionally throw an exception rather than passing -1 to alloc function
+ // CHECK: select
+ // CHECK: %[[PTR:.*]] = call i8* @_Zna{{.}}(i{{32|64}}
+ // CHECK: call void @llvm.memcpy{{.*}}(i8* align {{[0-9]+}} %[[PTR]], i8* align {{[0-9]+}} getelementptr inbounds ([4 x i8], [4 x i8]* @[[ABC4]], i32 0, i32 0), i32 4,
+ // CHECK: %[[REST:.*]] = getelementptr inbounds i8, i8* %[[PTR]], i32 4
+ // CHECK: %[[RESTSIZE:.*]] = sub {{.*}}, 4
+ // CHECK: call void @llvm.memset{{.*}}(i8* align {{[0-9]+}} %[[REST]], i8 0, i{{32|64}} %[[RESTSIZE]],
+ new char[n] { "abc" };
+}
+
+// CHECK-LABEL: define void @_Z12string_exactv
+void string_exact() {
+ // CHECK-NOT: icmp
+ // CHECK: %[[PTR:.*]] = call i8* @_Zna{{.}}(i{{32|64}} 4)
+ // CHECK: call void @llvm.memcpy{{.*}}(i8* align {{[0-9]+}} %[[PTR]], i8* align {{[0-9]+}} getelementptr inbounds ([4 x i8], [4 x i8]* @[[ABC4]], i32 0, i32 0), i32 4,
+ // CHECK-NOT: memset
+ new char[4] { "abc" };
+}
+
+// CHECK-LABEL: define void @_Z17string_sufficientv
+void string_sufficient() {
+ // CHECK-NOT: icmp
+ // CHECK: %[[PTR:.*]] = call i8* @_Zna{{.}}(i{{32|64}} 15)
+ // FIXME: For very large arrays, it would be preferable to emit a small copy and a memset.
+ // CHECK: call void @llvm.memcpy{{.*}}(i8* align {{[0-9]+}} %[[PTR]], i8* align {{[0-9]+}} getelementptr inbounds ([15 x i8], [15 x i8]* @[[ABC15]], i32 0, i32 0), i32 15,
+ // CHECK-NOT: memset
+ new char[15] { "abc" };
+}
+
+// CHECK-LABEL: define void @_Z10aggr_exactv
+void aggr_exact() {
+ // CHECK-NOT: icmp
+ // CHECK: %[[MEM:.*]] = call i8* @_Zna{{.}}(i{{32|64}} 16)
+ // CHECK: %[[PTR0:.*]] = bitcast i8* %[[MEM]] to %[[AGGR:.*]]*
+ // CHECK: %[[FIELD:.*]] = getelementptr inbounds %[[AGGR]], %[[AGGR]]* %[[PTR0]], i32 0, i32 0{{$}}
+ // CHECK: store i32 1, i32* %[[FIELD]]
+ // CHECK: %[[FIELD:.*]] = getelementptr inbounds %[[AGGR]], %[[AGGR]]* %[[PTR0]], i32 0, i32 1{{$}}
+ // CHECK: store i32 2, i32* %[[FIELD]]
+ // CHECK: %[[PTR1:.*]] = getelementptr inbounds %[[AGGR]], %[[AGGR]]* %[[PTR0]], i32 1{{$}}
+ // CHECK: %[[FIELD:.*]] = getelementptr inbounds %[[AGGR]], %[[AGGR]]* %[[PTR1]], i32 0, i32 0{{$}}
+ // CHECK: store i32 3, i32* %[[FIELD]]
+ // CHECK: %[[FIELD:.*]] = getelementptr inbounds %[[AGGR]], %[[AGGR]]* %[[PTR1]], i32 0, i32 1{{$}}
+ // CHECK: store i32 0, i32* %[[FIELD]]
+ // CHECK-NOT: store
+ // CHECK-NOT: memset
+ struct Aggr { int a, b; };
+ new Aggr[2] { 1, 2, 3 };
+}
+
+// CHECK-LABEL: define void @_Z15aggr_sufficienti
+void aggr_sufficient(int n) {
+ // CHECK: icmp ult i32 %{{.*}}, 2
+ // CHECK: %[[MEM:.*]] = call i8* @_Zna{{.}}(
+ // CHECK: %[[PTR0:.*]] = bitcast i8* %[[MEM]] to %[[AGGR:.*]]*
+ // CHECK: %[[FIELD:.*]] = getelementptr inbounds %[[AGGR]], %[[AGGR]]* %[[PTR0]], i32 0, i32 0{{$}}
+ // CHECK: store i32 1, i32* %[[FIELD]]
+ // CHECK: %[[FIELD:.*]] = getelementptr inbounds %[[AGGR]], %[[AGGR]]* %[[PTR0]], i32 0, i32 1{{$}}
+ // CHECK: store i32 2, i32* %[[FIELD]]
+ // CHECK: %[[PTR1:.*]] = getelementptr inbounds %[[AGGR]], %[[AGGR]]* %[[PTR0]], i32 1{{$}}
+ // CHECK: %[[FIELD:.*]] = getelementptr inbounds %[[AGGR]], %[[AGGR]]* %[[PTR1]], i32 0, i32 0{{$}}
+ // CHECK: store i32 3, i32* %[[FIELD]]
+ // CHECK: %[[FIELD:.*]] = getelementptr inbounds %[[AGGR]], %[[AGGR]]* %[[PTR1]], i32 0, i32 1{{$}}
+ // CHECK: store i32 0, i32* %[[FIELD]]
+ // CHECK: %[[PTR2:.*]] = getelementptr inbounds %[[AGGR]], %[[AGGR]]* %[[PTR1]], i32 1{{$}}
+ // CHECK: %[[REMAIN:.*]] = sub i32 {{.*}}, 16
+ // CHECK: %[[MEM:.*]] = bitcast %[[AGGR]]* %[[PTR2]] to i8*
+ // CHECK: call void @llvm.memset{{.*}}(i8* align {{[0-9]+}} %[[MEM]], i8 0, i32 %[[REMAIN]],
+ struct Aggr { int a, b; };
+ new Aggr[n] { 1, 2, 3 };
+}
+
+// SIO-LABEL: define void @_Z14constexpr_testv
+void constexpr_test() {
+ // SIO: call i8* @_Zna{{.}}(i32 4)
+ new int[0+1]{0};
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/new-operator-phi.cpp b/src/llvm-project/clang/test/CodeGenCXX/new-operator-phi.cpp
new file mode 100644
index 0000000..641734d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/new-operator-phi.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -emit-llvm-only -verify %s
+// expected-no-diagnostics
+// PR5454
+#include <stddef.h>
+
+struct X {static void * operator new(size_t size) throw(); X(int); };
+int a(), b();
+void b(int x)
+{
+ new X(x ? a() : b());
+}
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/new-overflow.cpp b/src/llvm-project/clang/test/CodeGenCXX/new-overflow.cpp
new file mode 100644
index 0000000..b27984f
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/new-overflow.cpp
@@ -0,0 +1,201 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o - | FileCheck %s
+
+// rdar://problem/9246208
+
+// Basic test.
+namespace test0 {
+ struct A {
+ A();
+ int x;
+ };
+
+ typedef A elt;
+
+ // CHECK: define [[A:%.*]]* @_ZN5test04testEs(i16 signext
+ // CHECK: [[N:%.*]] = sext i16 {{%.*}} to i32
+ // CHECK-NEXT: [[T0:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[N]], i32 4)
+ // CHECK-NEXT: [[T1:%.*]] = extractvalue { i32, i1 } [[T0]], 1
+ // CHECK-NEXT: [[T2:%.*]] = extractvalue { i32, i1 } [[T0]], 0
+ // CHECK-NEXT: [[T3:%.*]] = select i1 [[T1]], i32 -1, i32 [[T2]]
+ // CHECK-NEXT: call i8* @_Znaj(i32 [[T3]])
+ // CHECK: getelementptr inbounds {{.*}}, i32 [[N]]
+ elt *test(short s) {
+ return new elt[s];
+ }
+}
+
+// test0 with a nested array.
+namespace test1 {
+ struct A {
+ A();
+ int x;
+ };
+
+ typedef A elt[100];
+
+ // CHECK: define [100 x [[A:%.*]]]* @_ZN5test14testEs(i16 signext
+ // CHECK: [[N:%.*]] = sext i16 {{%.*}} to i32
+ // CHECK-NEXT: [[T0:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[N]], i32 400)
+ // CHECK-NEXT: [[T1:%.*]] = extractvalue { i32, i1 } [[T0]], 1
+ // CHECK-NEXT: [[T2:%.*]] = extractvalue { i32, i1 } [[T0]], 0
+ // CHECK-NEXT: [[T3:%.*]] = mul i32 [[N]], 100
+ // CHECK-NEXT: [[T4:%.*]] = select i1 [[T1]], i32 -1, i32 [[T2]]
+ // CHECK-NEXT: call i8* @_Znaj(i32 [[T4]])
+ // CHECK: getelementptr inbounds {{.*}}, i32 [[T3]]
+ elt *test(short s) {
+ return new elt[s];
+ }
+}
+
+// test1 with an array cookie.
+namespace test2 {
+ struct A {
+ A();
+ ~A();
+ int x;
+ };
+
+ typedef A elt[100];
+
+ // CHECK: define [100 x [[A:%.*]]]* @_ZN5test24testEs(i16 signext
+ // CHECK: [[N:%.*]] = sext i16 {{%.*}} to i32
+ // CHECK-NEXT: [[T0:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[N]], i32 400)
+ // CHECK-NEXT: [[T1:%.*]] = extractvalue { i32, i1 } [[T0]], 1
+ // CHECK-NEXT: [[T2:%.*]] = extractvalue { i32, i1 } [[T0]], 0
+ // CHECK-NEXT: [[T3:%.*]] = mul i32 [[N]], 100
+ // CHECK-NEXT: [[T4:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[T2]], i32 4)
+ // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T4]], 1
+ // CHECK-NEXT: [[T6:%.*]] = or i1 [[T1]], [[T5]]
+ // CHECK-NEXT: [[T7:%.*]] = extractvalue { i32, i1 } [[T4]], 0
+ // CHECK-NEXT: [[T8:%.*]] = select i1 [[T6]], i32 -1, i32 [[T7]]
+ // CHECK-NEXT: call i8* @_Znaj(i32 [[T8]])
+ // CHECK: getelementptr inbounds {{.*}}, i32 [[T3]]
+ elt *test(short s) {
+ return new elt[s];
+ }
+}
+
+// test0 with a 1-byte element.
+namespace test4 {
+ struct A {
+ A();
+ };
+
+ typedef A elt;
+
+ // CHECK: define [[A:%.*]]* @_ZN5test44testEs(i16 signext
+ // CHECK: [[N:%.*]] = sext i16 {{%.*}} to i32
+ // CHECK-NEXT: call i8* @_Znaj(i32 [[N]])
+ // CHECK: getelementptr inbounds {{.*}}, i32 [[N]]
+ elt *test(short s) {
+ return new elt[s];
+ }
+}
+
+// test4 with no sext required.
+namespace test5 {
+ struct A {
+ A();
+ };
+
+ typedef A elt;
+
+ // CHECK: define [[A:%.*]]* @_ZN5test54testEi(i32
+ // CHECK: [[N:%.*]] = load i32, i32*
+ // CHECK-NEXT: call i8* @_Znaj(i32 [[N]])
+ // CHECK: getelementptr inbounds {{.*}}, i32 [[N]]
+ elt *test(int s) {
+ return new elt[s];
+ }
+}
+
+// test0 with an unsigned size.
+namespace test6 {
+ struct A {
+ A();
+ int x;
+ };
+
+ typedef A elt;
+
+ // CHECK: define [[A:%.*]]* @_ZN5test64testEt(i16 zeroext
+ // CHECK: [[N:%.*]] = zext i16 {{%.*}} to i32
+ // CHECK-NEXT: [[T0:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[N]], i32 4)
+ // CHECK-NEXT: [[T1:%.*]] = extractvalue { i32, i1 } [[T0]], 1
+ // CHECK-NEXT: [[T2:%.*]] = extractvalue { i32, i1 } [[T0]], 0
+ // CHECK-NEXT: [[T3:%.*]] = select i1 [[T1]], i32 -1, i32 [[T2]]
+ // CHECK-NEXT: call i8* @_Znaj(i32 [[T3]])
+ // CHECK: getelementptr inbounds {{.*}}, i32 [[N]]
+ elt *test(unsigned short s) {
+ return new elt[s];
+ }
+}
+
+// test1 with an unsigned size.
+namespace test7 {
+ struct A {
+ A();
+ int x;
+ };
+
+ typedef A elt[100];
+
+ // CHECK: define [100 x [[A:%.*]]]* @_ZN5test74testEt(i16 zeroext
+ // CHECK: [[N:%.*]] = zext i16 {{%.*}} to i32
+ // CHECK-NEXT: [[T0:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[N]], i32 400)
+ // CHECK-NEXT: [[T1:%.*]] = extractvalue { i32, i1 } [[T0]], 1
+ // CHECK-NEXT: [[T2:%.*]] = extractvalue { i32, i1 } [[T0]], 0
+ // CHECK-NEXT: [[T3:%.*]] = mul i32 [[N]], 100
+ // CHECK-NEXT: [[T4:%.*]] = select i1 [[T1]], i32 -1, i32 [[T2]]
+ // CHECK-NEXT: call i8* @_Znaj(i32 [[T4]])
+ // CHECK: getelementptr inbounds {{.*}}, i32 [[T3]]
+ elt *test(unsigned short s) {
+ return new elt[s];
+ }
+}
+
+// test0 with a signed type larger than size_t.
+namespace test8 {
+ struct A {
+ A();
+ int x;
+ };
+
+ typedef A elt;
+
+ // CHECK: define [[A:%.*]]* @_ZN5test84testEx(i64
+ // CHECK: [[N:%.*]] = load i64, i64*
+ // CHECK-NEXT: [[T1:%.*]] = trunc i64 [[N]] to i32
+ // CHECK-NEXT: [[T2:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[T1]], i32 4)
+ // CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 1
+ // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T2]], 0
+ // CHECK-NEXT: [[T6:%.*]] = select i1 [[T3]], i32 -1, i32 [[T5]]
+ // CHECK-NEXT: call i8* @_Znaj(i32 [[T6]])
+ // CHECK: getelementptr inbounds {{.*}}, i32 [[T1]]
+ elt *test(long long s) {
+ return new elt[s];
+ }
+}
+
+// test8 with an unsigned type.
+namespace test9 {
+ struct A {
+ A();
+ int x;
+ };
+
+ typedef A elt;
+
+ // CHECK: define [[A:%.*]]* @_ZN5test94testEy(i64
+ // CHECK: [[N:%.*]] = load i64, i64*
+ // CHECK-NEXT: [[T1:%.*]] = trunc i64 [[N]] to i32
+ // CHECK-NEXT: [[T2:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[T1]], i32 4)
+ // CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 1
+ // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T2]], 0
+ // CHECK-NEXT: [[T6:%.*]] = select i1 [[T3]], i32 -1, i32 [[T5]]
+ // CHECK-NEXT: call i8* @_Znaj(i32 [[T6]])
+ // CHECK: getelementptr inbounds {{.*}}, i32 [[T1]]
+ elt *test(unsigned long long s) {
+ return new elt[s];
+ }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/new-with-default-arg.cpp b/src/llvm-project/clang/test/CodeGenCXX/new-with-default-arg.cpp
new file mode 100644
index 0000000..248cc9e
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/new-with-default-arg.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s
+// pr5547
+
+struct A {
+ void* operator new(__typeof(sizeof(int)));
+ A();
+};
+
+A* x() {
+ return new A;
+}
+
+struct B {
+ void* operator new(__typeof(sizeof(int)), int = 1, int = 4);
+ B(float);
+};
+
+B* y() {
+ new (3,4) B(1);
+ return new(1) B(2);
+}
+
+struct C {
+ void* operator new(__typeof(sizeof(int)), int, int = 4);
+ C();
+};
+
+C* z() {
+ new (3,4) C;
+ return new(1) C;
+}
+
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/new.cpp b/src/llvm-project/clang/test/CodeGenCXX/new.cpp
new file mode 100644
index 0000000..3bebc2a
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/new.cpp
@@ -0,0 +1,376 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -emit-llvm -o - | FileCheck %s
+
+typedef __typeof__(sizeof(0)) size_t;
+
+// Declare an 'operator new' template to tickle a bug in __builtin_operator_new.
+template<typename T> void *operator new(size_t, int (*)(T));
+
+// Ensure that this declaration doesn't cause operator new to lose its
+// 'noalias' attribute.
+void *operator new[](size_t);
+
+void t1() {
+ delete new int;
+ delete [] new int [3];
+}
+
+// CHECK: declare noalias i8* @_Znwm(i64) [[ATTR_NOBUILTIN:#[^ ]*]]
+// CHECK: declare void @_ZdlPv(i8*) [[ATTR_NOBUILTIN_NOUNWIND:#[^ ]*]]
+// CHECK: declare noalias i8* @_Znam(i64) [[ATTR_NOBUILTIN]]
+// CHECK: declare void @_ZdaPv(i8*) [[ATTR_NOBUILTIN_NOUNWIND]]
+
+namespace std {
+ struct nothrow_t {};
+}
+std::nothrow_t nothrow;
+
+// Declare the reserved placement operators.
+void *operator new(size_t, void*) throw();
+void operator delete(void*, void*) throw();
+void *operator new[](size_t, void*) throw();
+void operator delete[](void*, void*) throw();
+
+// Declare the replaceable global allocation operators.
+void *operator new(size_t, const std::nothrow_t &) throw();
+void *operator new[](size_t, const std::nothrow_t &) throw();
+void operator delete(void *, const std::nothrow_t &) throw();
+void operator delete[](void *, const std::nothrow_t &) throw();
+
+// Declare some other placemenet operators.
+void *operator new(size_t, void*, bool) throw();
+void *operator new[](size_t, void*, bool) throw();
+
+void t2(int* a) {
+ int* b = new (a) int;
+}
+
+struct S {
+ int a;
+};
+
+// POD types.
+void t3() {
+ int *a = new int(10);
+ _Complex int* b = new _Complex int(10i);
+
+ S s;
+ s.a = 10;
+ S *sp = new S(s);
+}
+
+// Non-POD
+struct T {
+ T();
+ int a;
+};
+
+void t4() {
+ // CHECK: call void @_ZN1TC1Ev
+ T *t = new T;
+}
+
+struct T2 {
+ int a;
+ T2(int, int);
+};
+
+void t5() {
+ // CHECK: call void @_ZN2T2C1Eii
+ T2 *t2 = new T2(10, 10);
+}
+
+int *t6() {
+ // Null check.
+ return new (0) int(10);
+}
+
+void t7() {
+ new int();
+}
+
+struct U {
+ ~U();
+};
+
+void t8(int n) {
+ new int[10];
+ new int[n];
+
+ // Non-POD
+ new T[10];
+ new T[n];
+
+ // Cookie required
+ new U[10];
+ new U[n];
+}
+
+void t9() {
+ bool b;
+
+ new bool(true);
+ new (&b) bool(true);
+}
+
+struct A {
+ void* operator new(__typeof(sizeof(int)), int, float, ...);
+ A();
+};
+
+A* t10() {
+ // CHECK: @_ZN1AnwEmifz
+ return new(1, 2, 3.45, 100) A;
+}
+
+// CHECK-LABEL: define void @_Z3t11i
+struct B { int a; };
+struct Bmemptr { int Bmemptr::* memptr; int a; };
+
+void t11(int n) {
+ // CHECK: call i8* @_Znwm
+ // CHECK: call void @llvm.memset.p0i8.i64(
+ B* b = new B();
+
+ // CHECK: call i8* @_Znam
+ // CHECK: {{call void.*llvm.memset.p0i8.i64.*i8 0, i64 %}}
+ B *b2 = new B[n]();
+
+ // CHECK: call i8* @_Znam
+ // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
+ // CHECK: br
+ Bmemptr *b_memptr = new Bmemptr[n]();
+
+ // CHECK: ret void
+}
+
+struct Empty { };
+
+// We don't need to initialize an empty class.
+// CHECK-LABEL: define void @_Z3t12v
+void t12() {
+ // CHECK: call i8* @_Znam
+ // CHECK-NOT: br
+ (void)new Empty[10];
+
+ // CHECK: call i8* @_Znam
+ // CHECK-NOT: br
+ (void)new Empty[10]();
+
+ // CHECK: ret void
+}
+
+// Zero-initialization
+// CHECK-LABEL: define void @_Z3t13i
+void t13(int n) {
+ // CHECK: call i8* @_Znwm
+ // CHECK: store i32 0, i32*
+ (void)new int();
+
+ // CHECK: call i8* @_Znam
+ // CHECK: {{call void.*llvm.memset.p0i8.i64.*i8 0, i64 %}}
+ (void)new int[n]();
+
+ // CHECK-NEXT: ret void
+}
+
+struct Alloc{
+ int x;
+ void* operator new[](size_t size);
+ void operator delete[](void* p);
+ ~Alloc();
+};
+
+void f() {
+ // CHECK: call i8* @_ZN5AllocnaEm(i64 808)
+ // CHECK: store i64 200
+ // CHECK: call void @_ZN5AllocD1Ev(
+ // CHECK: call void @_ZN5AllocdaEPv(i8*
+ delete[] new Alloc[10][20];
+ // CHECK: call i8* @_Znwm
+ // CHECK: call void @_ZdlPv(i8*
+ delete new bool;
+ // CHECK: ret void
+}
+
+namespace test15 {
+ struct A { A(); ~A(); };
+
+ // CHECK-LABEL: define void @_ZN6test156test0aEPv(
+ // CHECK: [[P:%.*]] = load i8*, i8**
+ // CHECK-NOT: icmp eq i8* [[P]], null
+ // CHECK-NOT: br i1
+ // CHECK: [[T0:%.*]] = bitcast i8* [[P]] to [[A:%.*]]*
+ // CHECK-NEXT: call void @_ZN6test151AC1Ev([[A]]* [[T0]])
+ void test0a(void *p) {
+ new (p) A();
+ }
+
+ // CHECK-LABEL: define void @_ZN6test156test0bEPv(
+ // CHECK: [[P0:%.*]] = load i8*, i8**
+ // CHECK: [[P:%.*]] = call i8* @_ZnwmPvb(i64 1, i8* [[P0]]
+ // CHECK-NEXT: icmp eq i8* [[P]], null
+ // CHECK-NEXT: br i1
+ // CHECK: [[T0:%.*]] = bitcast i8* [[P]] to [[A:%.*]]*
+ // CHECK-NEXT: call void @_ZN6test151AC1Ev([[A]]* [[T0]])
+ void test0b(void *p) {
+ new (p, true) A();
+ }
+
+ // CHECK-LABEL: define void @_ZN6test156test1aEPv(
+ // CHECK: [[P:%.*]] = load i8*, i8**
+ // CHECK-NOT: icmp eq i8* [[P]], null
+ // CHECK-NOT: br i1
+ // CHECK: [[BEGIN:%.*]] = bitcast i8* [[P]] to [[A:%.*]]*
+ // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]], [[A]]* [[BEGIN]], i64 5
+ // CHECK-NEXT: br label
+ // CHECK: [[CUR:%.*]] = phi [[A]]* [ [[BEGIN]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ]
+ // CHECK-NEXT: call void @_ZN6test151AC1Ev([[A]]* [[CUR]])
+ // CHECK-NEXT: [[NEXT]] = getelementptr inbounds [[A]], [[A]]* [[CUR]], i64 1
+ // CHECK-NEXT: [[DONE:%.*]] = icmp eq [[A]]* [[NEXT]], [[END]]
+ // CHECK-NEXT: br i1 [[DONE]]
+ void test1a(void *p) {
+ new (p) A[5];
+ }
+
+ // CHECK-LABEL: define void @_ZN6test156test1bEPv(
+ // CHECK: [[P0:%.*]] = load i8*, i8**
+ // CHECK: [[P:%.*]] = call i8* @_ZnamPvb(i64 13, i8* [[P0]]
+ // CHECK-NEXT: icmp eq i8* [[P]], null
+ // CHECK-NEXT: br i1
+ // CHECK: [[AFTER_COOKIE:%.*]] = getelementptr inbounds i8, i8* [[P]], i64 8
+ // CHECK: [[BEGIN:%.*]] = bitcast i8* [[AFTER_COOKIE]] to [[A:%.*]]*
+ // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]], [[A]]* [[BEGIN]], i64 5
+ // CHECK-NEXT: br label
+ // CHECK: [[CUR:%.*]] = phi [[A]]* [ [[BEGIN]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ]
+ // CHECK-NEXT: call void @_ZN6test151AC1Ev([[A]]* [[CUR]])
+ // CHECK-NEXT: [[NEXT]] = getelementptr inbounds [[A]], [[A]]* [[CUR]], i64 1
+ // CHECK-NEXT: [[DONE:%.*]] = icmp eq [[A]]* [[NEXT]], [[END]]
+ // CHECK-NEXT: br i1 [[DONE]]
+ void test1b(void *p) {
+ new (p, true) A[5];
+ }
+
+ // TODO: it's okay if all these size calculations get dropped.
+ // FIXME: maybe we should try to throw on overflow?
+ // CHECK-LABEL: define void @_ZN6test155test2EPvi(
+ // CHECK: [[N:%.*]] = load i32, i32*
+ // CHECK-NEXT: [[T0:%.*]] = sext i32 [[N]] to i64
+ // CHECK-NEXT: [[P:%.*]] = load i8*, i8**
+ // CHECK: [[BEGIN:%.*]] = bitcast i8* [[P]] to [[A:%.*]]*
+ // CHECK-NEXT: [[ISEMPTY:%.*]] = icmp eq i64 [[T0]], 0
+ // CHECK-NEXT: br i1 [[ISEMPTY]],
+ // CHECK: [[END:%.*]] = getelementptr inbounds [[A]], [[A]]* [[BEGIN]], i64 [[T0]]
+ // CHECK-NEXT: br label
+ // CHECK: [[CUR:%.*]] = phi [[A]]* [ [[BEGIN]],
+ // CHECK-NEXT: call void @_ZN6test151AC1Ev([[A]]* [[CUR]])
+ void test2(void *p, int n) {
+ new (p) A[n];
+ }
+}
+
+namespace PR10197 {
+ // CHECK-LABEL: define weak_odr void @_ZN7PR101971fIiEEvv()
+ template<typename T>
+ void f() {
+ // CHECK: [[CALL:%.*]] = call i8* @_Znwm
+ // CHECK-NEXT: [[CASTED:%.*]] = bitcast i8* [[CALL]] to
+ new T;
+ // CHECK-NEXT: ret void
+ }
+
+ template void f<int>();
+}
+
+namespace PR11523 {
+ class MyClass;
+ typedef int MyClass::* NewTy;
+ // CHECK-LABEL: define i64* @_ZN7PR115231fEv
+ // CHECK: store i64 -1
+ NewTy* f() { return new NewTy[2](); }
+}
+
+namespace PR11757 {
+ // Make sure we elide the copy construction.
+ struct X { X(); X(const X&); };
+ X* a(X* x) { return new X(X()); }
+ // CHECK: define {{.*}} @_ZN7PR117571aEPNS_1XE
+ // CHECK: [[CALL:%.*]] = call i8* @_Znwm
+ // CHECK-NEXT: [[CASTED:%.*]] = bitcast i8* [[CALL]] to
+ // CHECK-NEXT: call void @_ZN7PR117571XC1Ev({{.*}}* [[CASTED]])
+ // CHECK-NEXT: ret {{.*}} [[CASTED]]
+}
+
+namespace PR13380 {
+ struct A { A() {} };
+ struct B : public A { int x; };
+ // CHECK-LABEL: define i8* @_ZN7PR133801fEv
+ // CHECK: call i8* @_Znam(
+ // CHECK: call void @llvm.memset.p0i8
+ // CHECK-NEXT: call void @_ZN7PR133801BC1Ev
+ void* f() { return new B[2](); }
+}
+
+struct MyPlacementType {} mpt;
+void *operator new(size_t, MyPlacementType);
+
+namespace N3664 {
+ struct S { S() throw(int); };
+
+ // CHECK-LABEL: define void @_ZN5N36641fEv
+ void f() {
+ // CHECK: call i8* @_Znwm(i64 4) [[ATTR_BUILTIN_NEW:#[^ ]*]]
+ int *p = new int; // expected-note {{allocated with 'new' here}}
+ // CHECK: call void @_ZdlPv({{.*}}) [[ATTR_BUILTIN_DELETE:#[^ ]*]]
+ delete p;
+
+ // CHECK: call i8* @_Znam(i64 12) [[ATTR_BUILTIN_NEW]]
+ int *q = new int[3];
+ // CHECK: call void @_ZdaPv({{.*}}) [[ATTR_BUILTIN_DELETE]]
+ delete[] p; // expected-warning {{'delete[]' applied to a pointer that was allocated with 'new'; did you mean 'delete'?}}
+
+ // CHECK: call i8* @_ZnamRKSt9nothrow_t(i64 3, {{.*}}) [[ATTR_BUILTIN_NOTHROW_NEW:#[^ ]*]]
+ (void) new (nothrow) S[3];
+
+ // CHECK: call i8* @_Znwm15MyPlacementType(i64 4){{$}}
+ (void) new (mpt) int;
+ }
+
+ // CHECK: declare noalias i8* @_ZnamRKSt9nothrow_t(i64, {{.*}}) [[ATTR_NOBUILTIN_NOUNWIND]]
+
+ // CHECK-LABEL: define void @_ZN5N36641gEv
+ void g() {
+ // It's OK for there to be attributes here, so long as we don't have a
+ // 'builtin' attribute.
+ // CHECK: call i8* @_Znwm(i64 4){{$}}
+ int *p = (int*)operator new(4);
+ // CHECK: call void @_ZdlPv({{.*}}) [[ATTR_NOUNWIND:#[^ ]*]]
+ operator delete(p);
+
+ // CHECK: call i8* @_Znam(i64 12){{$}}
+ int *q = (int*)operator new[](12);
+ // CHECK: call void @_ZdaPv({{.*}}) [[ATTR_NOUNWIND]]
+ operator delete [](p);
+
+ // CHECK: call i8* @_ZnamRKSt9nothrow_t(i64 3, {{.*}}) [[ATTR_NOUNWIND]]
+ (void) operator new[](3, nothrow);
+ }
+}
+
+namespace builtins {
+ // CHECK-LABEL: define void @_ZN8builtins1fEv
+ void f() {
+ // CHECK: call i8* @_Znwm(i64 4) [[ATTR_BUILTIN_NEW]]
+ // CHECK: call void @_ZdlPv({{.*}}) [[ATTR_BUILTIN_DELETE]]
+ __builtin_operator_delete(__builtin_operator_new(4));
+ }
+}
+
+// CHECK-DAG: attributes [[ATTR_NOBUILTIN]] = {{[{].*}} nobuiltin {{.*[}]}}
+// CHECK-DAG: attributes [[ATTR_NOBUILTIN_NOUNWIND]] = {{[{].*}} nobuiltin nounwind {{.*[}]}}
+
+// CHECK-DAG: attributes [[ATTR_BUILTIN_NEW]] = {{[{].*}} builtin {{.*[}]}}
+// CHECK-DAG: attributes [[ATTR_BUILTIN_DELETE]] = {{[{].*}} builtin {{.*[}]}}
+
+// The ([^b}|...) monstrosity is matching a character that's not the start of 'builtin'.
+// Add more letters if this matches some other attribute.
+// CHECK-DAG: attributes [[ATTR_NOUNWIND]] = {{([^b]|b[^u]|bu[^i]|bui[^l])*}} nounwind {{([^b]|b[^u]|bu[^i]|bui[^l])*$}}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/no-elide-constructors.cpp b/src/llvm-project/clang/test/CodeGenCXX/no-elide-constructors.cpp
new file mode 100644
index 0000000..ecb350f
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/no-elide-constructors.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -std=c++98 -triple i386-unknown-unknown -fno-elide-constructors -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-CXX98
+// RUN: %clang_cc1 -std=c++11 -triple i386-unknown-unknown -fno-elide-constructors -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-CXX11
+// RUN: %clang_cc1 -std=c++98 -triple i386-unknown-unknown -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-CXX98-ELIDE
+// RUN: %clang_cc1 -std=c++11 -triple i386-unknown-unknown -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-CXX11-ELIDE
+
+// Reduced from PR12208
+class X {
+public:
+ X();
+ X(const X&);
+#if __cplusplus >= 201103L
+ X(X&&);
+#endif
+ ~X();
+};
+
+// CHECK-LABEL: define void @_Z4Testv(
+X Test()
+{
+ X x;
+
+ // Check that the copy constructor for X is called with result variable as
+ // sret argument.
+ // CHECK-CXX98: call void @_ZN1XC1ERKS_(
+ // CHECK-CXX11: call void @_ZN1XC1EOS_(
+ // CHECK-CXX98-ELIDE-NOT: call void @_ZN1XC1ERKS_(
+ // CHECK-CXX11-ELIDE-NOT: call void @_ZN1XC1EOS_(
+
+ // Make sure that the destructor for X is called.
+ // FIXME: This call is present even in the -ELIDE runs, but is guarded by a
+ // branch that is never taken in those cases. We could generate better IR
+ // here.
+ // CHECK: call void @_ZN1XD1Ev(
+ return x;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/no-exceptions.cpp b/src/llvm-project/clang/test/CodeGenCXX/no-exceptions.cpp
new file mode 100644
index 0000000..b970ef2
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/no-exceptions.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+void g();
+
+// CHECK: define void @_Z1fv() [[NUW:#[0-9]+]]
+void f() throw (int) {
+
+ // CHECK-NOT: invoke void @_Z1gv
+ g();
+ // CHECK: call void @_Z1gv()
+ // CHECK: ret void
+}
+
+// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/no-lto-unit.cpp b/src/llvm-project/clang/test/CodeGenCXX/no-lto-unit.cpp
new file mode 100644
index 0000000..3797f07
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/no-lto-unit.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -flto=thin -triple x86_64-unknown-linux -fvisibility hidden -emit-llvm-bc -o %t %s
+// RUN: llvm-dis -o - %t | FileCheck %s
+// RUN: %clang_cc1 -flto=thin -flto-unit -fno-lto-unit -triple x86_64-unknown-linux -fvisibility hidden -emit-llvm-bc -o %t %s
+// RUN: llvm-dis -o - %t | FileCheck %s
+// RUN: llvm-bcanalyzer -dump %t | FileCheck %s --check-prefix=NOLTOUNIT
+// NOLTOUNIT: <FLAGS op0=0/>
+
+// CHECK-NOT: !type
+class A {
+ virtual void f() {}
+};
+
+A *f() {
+ return new A;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/no-opt-volatile-memcpy.cpp b/src/llvm-project/clang/test/CodeGenCXX/no-opt-volatile-memcpy.cpp
new file mode 100644
index 0000000..a51421c
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/no-opt-volatile-memcpy.cpp
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -triple=x86_64-apple-darwin -emit-llvm -o - %s | FileCheck %s
+// rdar://11861085
+
+struct s {
+ char filler [128];
+ volatile int x;
+};
+
+struct s gs;
+
+void foo (void) {
+ struct s ls;
+ ls = ls;
+ gs = gs;
+ ls = gs;
+}
+// CHECK-LABEL: define void @_Z3foov()
+// CHECK: %[[LS:.*]] = alloca %struct.s, align 4
+// CHECK-NEXT: %[[ZERO:.*]] = bitcast %struct.s* %[[LS]] to i8*
+// CHECK-NEXT: %[[ONE:.*]] = bitcast %struct.s* %[[LS]] to i8*
+// CHECK-NEXT: call void @llvm.memcpy.{{.*}}(i8* align 4 %[[ZERO]], i8* align 4 %[[ONE]], i64 132, i1 true)
+// CHECK-NEXT: call void @llvm.memcpy.{{.*}}(i8* align 4 getelementptr inbounds (%struct.s, %struct.s* @gs, i32 0, i32 0, i32 0), i8* align 4 getelementptr inbounds (%struct.s, %struct.s* @gs, i32 0, i32 0, i32 0), i64 132, i1 true)
+// CHECK-NEXT: %[[TWO:.*]] = bitcast %struct.s* %[[LS]] to i8*
+// CHECK-NEXT: call void @llvm.memcpy.{{.*}}(i8* align 4 %[[TWO]], i8* align 4 getelementptr inbounds (%struct.s, %struct.s* @gs, i32 0, i32 0, i32 0), i64 132, i1 true)
+
+
+struct s1 {
+ struct s y;
+};
+
+struct s1 s;
+
+void fee (void) {
+ s = s;
+ s.y = gs;
+}
+// CHECK-LABEL: define void @_Z3feev()
+// CHECK: call void @llvm.memcpy.{{.*}}(i8* align 4 getelementptr inbounds (%struct.s1, %struct.s1* @s, i32 0, i32 0, i32 0, i32 0), i8* align 4 getelementptr inbounds (%struct.s1, %struct.s1* @s, i32 0, i32 0, i32 0, i32 0), i64 132, i1 true)
+// CHECK-NEXT: call void @llvm.memcpy.{{.*}}(i8* align 4 getelementptr inbounds (%struct.s1, %struct.s1* @s, i32 0, i32 0, i32 0, i32 0), i8* align 4 getelementptr inbounds (%struct.s, %struct.s* @gs, i32 0, i32 0, i32 0), i64 132, i1 true)
+
+struct d : s1 {
+};
+
+d gd;
+
+void gorf(void) {
+ gd = gd;
+}
+// CHECK-LABEL: define void @_Z4gorfv()
+// CHECK: call void @llvm.memcpy.{{.*}}(i8* align 4 getelementptr inbounds (%struct.d, %struct.d* @gd, i32 0, i32 0, i32 0, i32 0, i32 0), i8* align 4 getelementptr inbounds (%struct.d, %struct.d* @gd, i32 0, i32 0, i32 0, i32 0, i32 0), i64 132, i1 true)
diff --git a/src/llvm-project/clang/test/CodeGenCXX/no_destroy.cpp b/src/llvm-project/clang/test/CodeGenCXX/no_destroy.cpp
new file mode 100644
index 0000000..93e6ce1
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/no_destroy.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 %s -emit-llvm -triple x86_64-apple-macosx10.13.0 -o - | FileCheck %s
+
+struct NonTrivial {
+ ~NonTrivial();
+};
+
+// CHECK-NOT: __cxa_atexit{{.*}}_ZN10NonTrivialD1Ev
+[[clang::no_destroy]] NonTrivial nt1;
+// CHECK-NOT: _tlv_atexit{{.*}}_ZN10NonTrivialD1Ev
+[[clang::no_destroy]] thread_local NonTrivial nt2;
+
+struct NonTrivial2 {
+ ~NonTrivial2();
+};
+
+// CHECK: __cxa_atexit{{.*}}_ZN11NonTrivial2D1Ev
+NonTrivial2 nt21;
+// CHECK: _tlv_atexit{{.*}}_ZN11NonTrivial2D1Ev
+thread_local NonTrivial2 nt22;
+
+void f() {
+ // CHECK: __cxa_atexit{{.*}}_ZN11NonTrivial2D1Ev
+ static NonTrivial2 nt21;
+ // CHECK: _tlv_atexit{{.*}}_ZN11NonTrivial2D1Ev
+ thread_local NonTrivial2 nt22;
+}
+
+// CHECK: __cxa_atexit{{.*}}_ZN10NonTrivialD1Ev
+[[clang::always_destroy]] NonTrivial nt3;
+// CHECK: _tlv_atexit{{.*}}_ZN10NonTrivialD1Ev
+[[clang::always_destroy]] thread_local NonTrivial nt4;
diff --git a/src/llvm-project/clang/test/CodeGenCXX/noescape.cpp b/src/llvm-project/clang/test/CodeGenCXX/noescape.cpp
new file mode 100644
index 0000000..40bc839
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/noescape.cpp
@@ -0,0 +1,96 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm -fblocks -o - %s | FileCheck %s
+
+struct S {
+ int a[4];
+ S(int *, int * __attribute__((noescape)));
+ S &operator=(int * __attribute__((noescape)));
+ void m0(int *, int * __attribute__((noescape)));
+ virtual void vm1(int *, int * __attribute__((noescape)));
+};
+
+// CHECK: define void @_ZN1SC2EPiS0_(%struct.S* {{.*}}, {{.*}}, {{.*}} nocapture)
+// CHECK: define void @_ZN1SC1EPiS0_(%struct.S* {{.*}}, {{.*}}, {{.*}} nocapture) {{.*}} {
+// CHECK: call void @_ZN1SC2EPiS0_(%struct.S* {{.*}}, {{.*}}, {{.*}} nocapture {{.*}})
+
+S::S(int *, int * __attribute__((noescape))) {}
+
+// CHECK: define {{.*}} %struct.S* @_ZN1SaSEPi(%struct.S* {{.*}}, {{.*}} nocapture)
+S &S::operator=(int * __attribute__((noescape))) { return *this; }
+
+// CHECK: define void @_ZN1S2m0EPiS0_(%struct.S* {{.*}}, {{.*}} nocapture)
+void S::m0(int *, int * __attribute__((noescape))) {}
+
+// CHECK: define void @_ZN1S3vm1EPiS0_(%struct.S* {{.*}}, {{.*}} nocapture)
+void S::vm1(int *, int * __attribute__((noescape))) {}
+
+// CHECK-LABEL: define void @_Z5test0P1SPiS1_(
+// CHECK: call void @_ZN1SC1EPiS0_(%struct.S* {{.*}}, {{.*}}, {{.*}} nocapture {{.*}})
+// CHECK: call {{.*}} %struct.S* @_ZN1SaSEPi(%struct.S* {{.*}}, {{.*}} nocapture {{.*}})
+// CHECK: call void @_ZN1S2m0EPiS0_(%struct.S* {{.*}}, {{.*}}, {{.*}} nocapture {{.*}})
+// CHECK: call void {{.*}}(%struct.S* {{.*}}, {{.*}}, {{.*}} nocapture {{.*}})
+void test0(S *s, int *p0, int *p1) {
+ S t(p0, p1);
+ t = p1;
+ s->m0(p0, p1);
+ s->vm1(p0, p1);
+}
+
+namespace std {
+ typedef decltype(sizeof(0)) size_t;
+}
+
+// CHECK: define {{.*}} @_ZnwmPv({{.*}}, {{.*}} nocapture {{.*}})
+void *operator new(std::size_t, void * __attribute__((noescape)) p) {
+ return p;
+}
+
+// CHECK-LABEL: define i8* @_Z5test1Pv(
+// CHECK : %call = call {{.*}} @_ZnwmPv({{.*}}, {{.*}} nocapture {{.*}})
+void *test1(void *p0) {
+ return ::operator new(16, p0);
+}
+
+// CHECK-LABEL: define void @_Z5test2PiS_(
+// CHECK: call void @"_ZZ5test2PiS_ENK3$_0clES_S_"({{.*}}, {{.*}}, {{.*}} nocapture {{.*}})
+// CHECK: define internal void @"_ZZ5test2PiS_ENK3$_0clES_S_"({{.*}}, {{.*}}, {{.*}} nocapture)
+void test2(int *p0, int *p1) {
+ auto t = [](int *, int * __attribute__((noescape))){};
+ t(p0, p1);
+}
+
+// CHECK-LABEL: define void @_Z5test3PFvU8noescapePiES_(
+// CHECK: call void {{.*}}(i32* nocapture {{.*}})
+typedef void (*NoEscapeFunc)(__attribute__((noescape)) int *);
+
+void test3(NoEscapeFunc f, int *p) {
+ f(p);
+}
+
+namespace TestByref {
+
+struct S {
+ S();
+ ~S();
+ S(const S &);
+ int a;
+};
+
+typedef void (^BlockTy)(void);
+S &getS();
+void noescapefunc(__attribute__((noescape)) BlockTy);
+
+// Check that __block variables with reference types are handled correctly.
+
+// CHECK: define void @_ZN9TestByref4testEv(
+// CHECK: %[[X:.*]] = alloca %[[STRUCT_TESTBYREF:.*]]*, align 8
+// CHECK: %[[BLOCK:.*]] = alloca <{ i8*, i32, i32, i8*, %{{.*}}*, %[[STRUCT_TESTBYREF]]* }>, align 8
+// CHECK: %[[BLOCK_CAPTURED:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %{{.*}}*, %[[STRUCT_TESTBYREF]]* }>, <{ i8*, i32, i32, i8*, %{{.*}}*, %[[STRUCT_TESTBYREF]]* }>* %[[BLOCK]], i32 0, i32 5
+// CHECK: %[[V0:.*]] = load %[[STRUCT_TESTBYREF]]*, %[[STRUCT_TESTBYREF]]** %[[X]], align 8
+// CHECK: store %[[STRUCT_TESTBYREF]]* %[[V0]], %[[STRUCT_TESTBYREF]]** %[[BLOCK_CAPTURED]], align 8
+
+void test() {
+ __block S &x = getS();
+ noescapefunc(^{ (void)x; });
+}
+
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/noexcept.cpp b/src/llvm-project/clang/test/CodeGenCXX/noexcept.cpp
new file mode 100644
index 0000000..9d90484
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/noexcept.cpp
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - -fcxx-exceptions -fexceptions -std=c++11 | FileCheck %s
+
+// rdar://11904428
+// Ensure that we call __cxa_begin_catch before calling
+// std::terminate in a noexcept function.
+namespace test0 {
+ void foo();
+
+ struct A {
+ A();
+ ~A();
+ };
+
+ void test() noexcept {
+ A a;
+ foo();
+ }
+}
+// CHECK-LABEL: define void @_ZN5test04testEv()
+// CHECK: [[EXN:%.*]] = alloca i8*
+// This goes to the terminate lpad.
+// CHECK: invoke void @_ZN5test01AC1Ev(
+// This goes to the cleanup-and-then-terminate lpad.
+// CHECK: invoke void @_ZN5test03fooEv()
+// Destructors don't throw by default in C++11.
+// CHECK: call void @_ZN5test01AD1Ev(
+// Cleanup lpad.
+// CHECK: [[T0:%.*]] = landingpad
+// CHECK-NEXT: catch i8* null
+// CHECK-NEXT: [[T1:%.*]] = extractvalue { i8*, i32 } [[T0]], 0
+// CHECK-NEXT: store i8* [[T1]], i8** [[EXN]]
+// (Calling this destructor is not technically required.)
+// CHECK: call void @_ZN5test01AD1Ev(
+// CHECK-NEXT: br label
+// The terminate landing pad jumps in here for some reason.
+// CHECK: [[T0:%.*]] = landingpad
+// CHECK-NEXT: catch i8* null
+// CHECK-NEXT: [[T1:%.*]] = extractvalue { i8*, i32 } [[T0]], 0
+// CHECK-NEXT: call void @__clang_call_terminate(i8* [[T1]])
+// CHECK-NEXT: unreachable
+// The terminate handler chained to by the cleanup lpad.
+// CHECK: [[T0:%.*]] = load i8*, i8** [[EXN]]
+// CHECK-NEXT: call void @__clang_call_terminate(i8* [[T0]])
+// CHECK-NEXT: unreachable
+
+// CHECK-LABEL: define linkonce_odr hidden void @__clang_call_terminate(
+// CHECK: call i8* @__cxa_begin_catch(
+// CHECK-NEXT: call void @_ZSt9terminatev()
+// CHECK-NEXT: unreachable
diff --git a/src/llvm-project/clang/test/CodeGenCXX/noinline-template.cpp b/src/llvm-project/clang/test/CodeGenCXX/noinline-template.cpp
new file mode 100644
index 0000000..3dd4366
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/noinline-template.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 %s -emit-llvm -triple %itanium_abi_triple -o - | FileCheck %s
+
+// This was a problem in Sema, but only shows up as noinline missing
+// in CodeGen.
+
+// CHECK: define linkonce_odr {{.*}}void @_ZN6VectorIiE13growStorageByEv(%struct.Vector* %this) [[NI:#[0-9]+]]
+
+template <class Ty> struct Vector {
+ void growStorageBy();
+};
+template <class T> __attribute__((noinline)) void Vector<T>::growStorageBy() {
+}
+void foo() {
+ Vector<int> strs;
+ strs.growStorageBy();
+}
+
+// CHECK: attributes [[NI]] = { noinline nounwind{{.*}} }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/nonconst-init.cpp b/src/llvm-project/clang/test/CodeGenCXX/nonconst-init.cpp
new file mode 100644
index 0000000..21129b9
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/nonconst-init.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s
+
+int a();
+// CHECK: call i32 @_Z1av()
+struct x {int x, y : 10;} x = {1, a()};
diff --git a/src/llvm-project/clang/test/CodeGenCXX/nrvo-noreturn.cpp b/src/llvm-project/clang/test/CodeGenCXX/nrvo-noreturn.cpp
new file mode 100644
index 0000000..a8259ca
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/nrvo-noreturn.cpp
@@ -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/src/llvm-project/clang/test/CodeGenCXX/nrvo.cpp b/src/llvm-project/clang/test/CodeGenCXX/nrvo.cpp
new file mode 100644
index 0000000..0f359b9
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/nrvo.cpp
@@ -0,0 +1,224 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -O1 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -O1 -fcxx-exceptions -fexceptions -std=c++03 -o - %s | FileCheck --check-prefixes=CHECK-EH,CHECK-EH-03 %s
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -O1 -fcxx-exceptions -fexceptions -std=c++11 -o - %s | FileCheck --check-prefixes=CHECK-EH,CHECK-EH-11 %s
+
+// Test code generation for the named return value optimization.
+class X {
+public:
+ X();
+ X(const X&);
+ ~X();
+};
+
+template<typename T> struct Y {
+ Y();
+ static Y f() {
+ Y y;
+ return y;
+ }
+};
+
+// CHECK-LABEL: define void @_Z5test0v
+// CHECK-EH-LABEL: define void @_Z5test0v
+X test0() {
+ X x;
+ // CHECK: call {{.*}} @_ZN1XC1Ev
+ // CHECK-NEXT: ret void
+
+ // CHECK-EH: call {{.*}} @_ZN1XC1Ev
+ // CHECK-EH-NEXT: ret void
+ return x;
+}
+
+// CHECK-LABEL: define void @_Z5test1b(
+// CHECK-EH-LABEL: define void @_Z5test1b(
+X test1(bool B) {
+ // CHECK: tail call {{.*}} @_ZN1XC1Ev
+ // CHECK-NEXT: ret void
+ X x;
+ if (B)
+ return (x);
+ return x;
+ // CHECK-EH: tail call {{.*}} @_ZN1XC1Ev
+ // CHECK-EH-NEXT: ret void
+}
+
+// CHECK-LABEL: define void @_Z5test2b
+// CHECK-EH-LABEL: define void @_Z5test2b
+// CHECK-EH-SAME: personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+X test2(bool B) {
+ // No NRVO.
+
+ X x;
+ X y;
+ if (B)
+ return y;
+ return x;
+
+ // CHECK: call {{.*}} @_ZN1XC1Ev
+ // CHECK-NEXT: {{.*}} getelementptr inbounds %class.X, %class.X* %y, i32 0, i32 0
+ // CHECK-NEXT: call void @llvm.lifetime.start
+ // CHECK-NEXT: call {{.*}} @_ZN1XC1Ev
+ // CHECK: call {{.*}} @_ZN1XC1ERKS_
+ // CHECK: call {{.*}} @_ZN1XC1ERKS_
+ // CHECK: call {{.*}} @_ZN1XD1Ev
+ // CHECK-NEXT: call void @llvm.lifetime.end
+ // CHECK: call {{.*}} @_ZN1XD1Ev
+ // CHECK-NEXT: call void @llvm.lifetime.end
+ // CHECK: ret void
+
+ // The block ordering in the -fexceptions IR is unfortunate.
+
+ // CHECK-EH: call void @llvm.lifetime.start
+ // CHECK-EH-NEXT: call {{.*}} @_ZN1XC1Ev
+ // CHECK-EH: call void @llvm.lifetime.start
+ // CHECK-EH-NEXT: invoke {{.*}} @_ZN1XC1Ev
+ // -> %invoke.cont, %lpad
+
+ // %invoke.cont:
+ // CHECK-EH: br i1
+ // -> %if.then, %if.end
+
+ // %if.then: returning 'x'
+ // CHECK-EH: invoke {{.*}} @_ZN1XC1ERKS_
+ // -> %cleanup, %lpad1
+
+ // %lpad: landing pad for ctor of 'y', dtor of 'y'
+ // CHECK-EH: [[CAUGHTVAL:%.*]] = landingpad { i8*, i32 }
+ // CHECK-EH-NEXT: cleanup
+ // CHECK-EH-NEXT: extractvalue { i8*, i32 } [[CAUGHTVAL]], 0
+ // CHECK-EH-NEXT: extractvalue { i8*, i32 } [[CAUGHTVAL]], 1
+ // CHECK-EH-NEXT: br label
+ // -> %eh.cleanup
+
+ // %lpad1: landing pad for return copy ctors, EH cleanup for 'y'
+ // CHECK-EH-03: invoke {{.*}} @_ZN1XD1Ev
+ // -> %eh.cleanup, %terminate.lpad
+ // CHECK-EH-11: call {{.*}} @_ZN1XD1Ev
+
+ // %if.end: returning 'y'
+ // CHECK-EH: invoke {{.*}} @_ZN1XC1ERKS_
+ // -> %cleanup, %lpad1
+
+ // %cleanup: normal cleanup for 'y'
+ // CHECK-EH-03: invoke {{.*}} @_ZN1XD1Ev
+ // -> %invoke.cont11, %lpad
+ // CHECK-EH-11: call {{.*}} @_ZN1XD1Ev
+
+ // %invoke.cont11: normal cleanup for 'x'
+ // CHECK-EH: call void @llvm.lifetime.end
+ // CHECK-EH-NEXT: call {{.*}} @_ZN1XD1Ev
+ // CHECK-EH-NEXT: call void @llvm.lifetime.end
+ // CHECK-EH-NEXT: ret void
+
+ // %eh.cleanup: EH cleanup for 'x'
+ // CHECK-EH-03: invoke {{.*}} @_ZN1XD1Ev
+ // -> %invoke.cont17, %terminate.lpad
+ // CHECK-EH-11: call {{.*}} @_ZN1XD1Ev
+
+ // %invoke.cont17: rethrow block for %eh.cleanup.
+ // This really should be elsewhere in the function.
+ // CHECK-EH: resume { i8*, i32 }
+
+ // %terminate.lpad: terminate landing pad.
+ // CHECK-EH-03: [[T0:%.*]] = landingpad { i8*, i32 }
+ // CHECK-EH-03-NEXT: catch i8* null
+ // CHECK-EH-03-NEXT: [[T1:%.*]] = extractvalue { i8*, i32 } [[T0]], 0
+ // CHECK-EH-03-NEXT: call void @__clang_call_terminate(i8* [[T1]]) [[NR_NUW:#[0-9]+]]
+ // CHECK-EH-03-NEXT: unreachable
+
+}
+
+// CHECK-LABEL: define void @_Z5test3b
+X test3(bool B) {
+ // CHECK: tail call {{.*}} @_ZN1XC1Ev
+ // CHECK-NOT: call {{.*}} @_ZN1XC1ERKS_
+ // CHECK: call {{.*}} @_ZN1XC1Ev
+ // CHECK: call {{.*}} @_ZN1XC1ERKS_
+ if (B) {
+ X y;
+ return y;
+ }
+ // FIXME: we should NRVO this variable too.
+ X x;
+ return x;
+}
+
+extern "C" void exit(int) throw();
+
+// CHECK-LABEL: define void @_Z5test4b
+X test4(bool B) {
+ {
+ // CHECK: tail call {{.*}} @_ZN1XC1Ev
+ X x;
+ // CHECK: br i1
+ if (B)
+ return x;
+ }
+ // CHECK: tail call {{.*}} @_ZN1XD1Ev
+ // CHECK: tail call void @exit(i32 1)
+ exit(1);
+}
+
+#ifdef __EXCEPTIONS
+// CHECK-EH-LABEL: define void @_Z5test5
+void may_throw();
+X test5() {
+ try {
+ may_throw();
+ } catch (X x) {
+ // CHECK-EH: invoke {{.*}} @_ZN1XC1ERKS_
+ // CHECK-EH: call void @__cxa_end_catch()
+ // CHECK-EH: ret void
+ return x;
+ }
+}
+#endif
+
+// rdar://problem/10430868
+// CHECK-LABEL: define void @_Z5test6v
+X test6() {
+ X a __attribute__((aligned(8)));
+ return a;
+ // CHECK: [[A:%.*]] = alloca [[X:%.*]], align 8
+ // CHECK-NEXT: [[PTR:%.*]] = getelementptr inbounds %class.X, %class.X* [[A]], i32 0, i32 0
+ // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull [[PTR]])
+ // CHECK-NEXT: call {{.*}} @_ZN1XC1Ev([[X]]* nonnull [[A]])
+ // CHECK-NEXT: call {{.*}} @_ZN1XC1ERKS_([[X]]* {{%.*}}, [[X]]* nonnull dereferenceable({{[0-9]+}}) [[A]])
+ // CHECK-NEXT: call {{.*}} @_ZN1XD1Ev([[X]]* nonnull [[A]])
+ // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull [[PTR]])
+ // CHECK-NEXT: ret void
+}
+
+// CHECK-LABEL: define void @_Z5test7b
+X test7(bool b) {
+ // CHECK: tail call {{.*}} @_ZN1XC1Ev
+ // CHECK-NEXT: ret
+ if (b) {
+ X x;
+ return x;
+ }
+ return X();
+}
+
+// CHECK-LABEL: define void @_Z5test8b
+X test8(bool b) {
+ // CHECK: tail call {{.*}} @_ZN1XC1Ev
+ // CHECK-NEXT: ret
+ if (b) {
+ X x;
+ return x;
+ } else {
+ X y;
+ return y;
+ }
+}
+
+Y<int> test9() {
+ Y<int>::f();
+}
+
+// CHECK-LABEL: define linkonce_odr void @_ZN1YIiE1fEv
+// CHECK: tail call {{.*}} @_ZN1YIiEC1Ev
+
+// CHECK-EH-03: attributes [[NR_NUW]] = { noreturn nounwind }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/nullptr.cpp b/src/llvm-project/clang/test/CodeGenCXX/nullptr.cpp
new file mode 100644
index 0000000..e93f706
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/nullptr.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -std=c++11 -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() {
+ int* a = nullptr;
+}
+
+typedef decltype(nullptr) nullptr_t;
+
+nullptr_t get_nullptr();
+
+struct X { };
+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/src/llvm-project/clang/test/CodeGenCXX/observe-noexcept.cpp b/src/llvm-project/clang/test/CodeGenCXX/observe-noexcept.cpp
new file mode 100644
index 0000000..76046a6
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/observe-noexcept.cpp
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -triple powerpc64le-unknown-unknown -std=c++11 -fopenmp -fexceptions -fcxx-exceptions -O0 -emit-llvm %s -o - | FileCheck %s
+
+// Check that regions that install a terminate scope in the exception stack can
+// correctly generate complex arithmetic.
+
+// CHECK-LABEL: ffcomplex
+void ffcomplex (int a) {
+ double _Complex dc = (double)a;
+
+ // CHECK: call { double, double } @__muldc3(double %{{.+}}, double %{{.+}}, double %{{.+}}, double %{{.+}})
+ dc *= dc;
+ // CHECK: call {{.+}} @__kmpc_fork_call({{.+}} [[REGNAME1:@.*]] to void (i32*, i32*, ...)*), { double, double }* %{{.+}})
+ #pragma omp parallel
+ {
+ dc *= dc;
+ }
+ // CHECK: ret void
+}
+
+// CHECK: define internal {{.+}}[[REGNAME1]](
+// CHECK-NOT: invoke
+// CHECK: call { double, double } @__muldc3(double %{{.+}}, double %{{.+}}, double %{{.+}}, double %{{.+}})
+// CHECK-NOT: invoke
+// CHECK: ret void
+
+// Check if we are observing the function pointer attribute regardless what is
+// in the exception specification of the callees.
+void fnoexcp(void) noexcept;
+
+// CHECK-LABEL: foo
+void foo(int a, int b) {
+
+ void (*fptr)(void) noexcept = fnoexcp;
+
+ // CHECK: call {{.+}} @__kmpc_fork_call({{.+}} [[REGNAME2:@.*]] to void (i32*, i32*, ...)*), void ()** %{{.+}})
+ #pragma omp parallel
+ {
+ fptr();
+ }
+ // CHECK: ret void
+}
+
+// CHECK: define internal {{.+}}[[REGNAME2]](
+// CHECK-NOT: invoke
+// CHECK: call void %{{[0-9]+}}()
+// CHECK-NOT: invoke
+// CHECK: ret void
diff --git a/src/llvm-project/clang/test/CodeGenCXX/operator-new.cpp b/src/llvm-project/clang/test/CodeGenCXX/operator-new.cpp
new file mode 100644
index 0000000..dc1c36d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/operator-new.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -emit-llvm -o %t-1.ll %s
+// RUN: FileCheck -check-prefix SANE --input-file=%t-1.ll %s
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -emit-llvm -fno-assume-sane-operator-new -o %t-2.ll %s
+// RUN: FileCheck -check-prefix SANENOT --input-file=%t-2.ll %s
+
+
+class teste {
+ int A;
+public:
+ teste() : A(2) {}
+};
+
+void f1() {
+ // SANE: declare noalias i8* @_Znwj(
+ // SANENOT: declare i8* @_Znwj(
+ new teste();
+}
+
+// rdar://5739832 - operator new should check for overflow in multiply.
+void *f2(long N) {
+ return new int[N];
+
+// SANE: [[UWO:%.*]] = call {{.*}} @llvm.umul.with.overflow
+// SANE-NEXT: [[OVER:%.*]] = extractvalue {{.*}} [[UWO]], 1
+// SANE-NEXT: [[SUM:%.*]] = extractvalue {{.*}} [[UWO]], 0
+// SANE-NEXT: [[RESULT:%.*]] = select i1 [[OVER]], i32 -1, i32 [[SUM]]
+// SANE-NEXT: call i8* @_Znaj(i32 [[RESULT]])
+}
+
+// SANE: declare noalias i8* @_Znaj(
+// SANENOT: declare i8* @_Znaj(
diff --git a/src/llvm-project/clang/test/CodeGenCXX/optnone-and-attributes.cpp b/src/llvm-project/clang/test/CodeGenCXX/optnone-and-attributes.cpp
new file mode 100644
index 0000000..870d5e9
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/optnone-and-attributes.cpp
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 < %s -triple i386-mingw32 -fms-extensions -emit-llvm -x c++ | FileCheck %s
+
+// optnone wins over inlinehint.
+// Test that both func1 and func2 are marked optnone and noinline.
+
+// Definition with both optnone and inlinehint.
+__attribute__((optnone))
+inline int func1(int a) {
+ return a + a + a + a;
+}
+// CHECK: @_Z5func1i({{.*}}) [[OPTNONE:#[0-9]+]]
+
+// optnone declaration, inlinehint definition.
+__attribute__((optnone))
+int func2(int a);
+
+inline int func2(int a) {
+ return a + a + a + a;
+}
+// CHECK: @_Z5func2i({{.*}}) [[OPTNONE]]
+
+// Keep alive the definitions of func1 and func2.
+int foo() {
+ int val = func1(1);
+ return val + func2(2);
+}
+
+// optnone wins over minsize.
+__attribute__((optnone))
+int func3(int a);
+
+__attribute__((minsize))
+int func3(int a) {
+ return a + a + a + a;
+}
+// Same attribute set as everything else, therefore no 'minsize'.
+// CHECK: @_Z5func3i({{.*}}) [[OPTNONE]]
+
+
+// Verify that noreturn is compatible with optnone.
+__attribute__((noreturn))
+extern void exit_from_function();
+
+__attribute__((noreturn)) __attribute((optnone))
+extern void noreturn_function(int a) { exit_from_function(); }
+// CHECK: @_Z17noreturn_functioni({{.*}}) [[NORETURN:#[0-9]+]]
+
+
+// Verify that __declspec(noinline) is compatible with optnone.
+__declspec(noinline) __attribute__((optnone))
+void func4() { return; }
+// CHECK: @_Z5func4v() [[OPTNONE]]
+
+__declspec(noinline)
+extern void func5();
+
+__attribute__((optnone))
+void func5() { return; }
+// CHECK: @_Z5func5v() [[OPTNONE]]
+
+
+// Verify also that optnone can be used on dllexport functions.
+// Adding attribute optnone on a dllimport function has no effect.
+
+__attribute__((dllimport))
+__attribute__((optnone))
+int imported_optnone_func(int a);
+
+__attribute__((dllexport))
+__attribute__((optnone))
+int exported_optnone_func(int a) {
+ return imported_optnone_func(a); // use of imported func
+}
+// CHECK: @_Z21exported_optnone_funci({{.*}}) [[OPTNONE]]
+// CHECK: declare dllimport {{.*}} @_Z21imported_optnone_funci({{.*}}) [[DLLIMPORT:#[0-9]+]]
+
+
+// CHECK: attributes [[OPTNONE]] = { noinline {{.*}} optnone
+// CHECK: attributes [[NORETURN]] = { noinline noreturn {{.*}} optnone
+
+// CHECK: attributes [[DLLIMPORT]] =
+// CHECK-NOT: optnone
diff --git a/src/llvm-project/clang/test/CodeGenCXX/optnone-class-members.cpp b/src/llvm-project/clang/test/CodeGenCXX/optnone-class-members.cpp
new file mode 100644
index 0000000..b1d2f7b
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/optnone-class-members.cpp
@@ -0,0 +1,164 @@
+// RUN: %clang_cc1 < %s -triple %itanium_abi_triple -fms-extensions -O2 -disable-llvm-passes -emit-llvm -x c++ | FileCheck %s
+
+// Test attribute 'optnone' on methods:
+// -- member functions;
+// -- static member functions.
+
+// Verify that all methods of struct A are associated to the same attribute set.
+// The attribute set shall contain attributes 'noinline' and 'optnone'.
+
+struct A {
+ // Definition of an optnone static method.
+ __attribute__((optnone))
+ static int static_optnone_method(int a) {
+ return a + a;
+ }
+ // CHECK: @_ZN1A21static_optnone_methodEi({{.*}}) [[OPTNONE:#[0-9]+]]
+
+ // Definition of an optnone normal method.
+ __attribute__((optnone))
+ int optnone_method(int a) {
+ return a + a + a + a;
+ }
+ // CHECK: @_ZN1A14optnone_methodEi({{.*}}) [[OPTNONE]]
+
+ // Declaration of an optnone method with out-of-line definition
+ // that doesn't say optnone.
+ __attribute__((optnone))
+ int optnone_decl_method(int a);
+
+ // Methods declared without attribute optnone; the definitions will
+ // have attribute optnone, and we verify optnone wins.
+ __forceinline static int static_forceinline_method(int a);
+ __attribute__((always_inline)) int alwaysinline_method(int a);
+ __attribute__((noinline)) int noinline_method(int a);
+ __attribute__((minsize)) int minsize_method(int a);
+};
+
+void foo() {
+ A a;
+ A::static_optnone_method(4);
+ a.optnone_method(14);
+ a.optnone_decl_method(12);
+ A::static_forceinline_method(5);
+ a.alwaysinline_method(5);
+ a.noinline_method(6);
+ a.minsize_method(7);
+}
+
+// No attribute here, should still be on the definition.
+int A::optnone_decl_method(int a) {
+ return a;
+}
+// CHECK: @_ZN1A19optnone_decl_methodEi({{.*}}) [[OPTNONE]]
+
+// optnone implies noinline; therefore attribute noinline is added to
+// the set of function attributes.
+// forceinline is instead translated as 'always_inline'.
+// However 'noinline' wins over 'always_inline' and therefore
+// the resulting attributes for this method are: noinline + optnone
+__attribute__((optnone))
+int A::static_forceinline_method(int a) {
+ return a + a + a + a;
+}
+// CHECK: @_ZN1A25static_forceinline_methodEi({{.*}}) [[OPTNONE]]
+
+__attribute__((optnone))
+int A::alwaysinline_method(int a) {
+ return a + a + a + a;
+}
+// CHECK: @_ZN1A19alwaysinline_methodEi({{.*}}) [[OPTNONE]]
+
+// 'noinline' + 'noinline and optnone' = 'noinline and optnone'
+__attribute__((optnone))
+int A::noinline_method(int a) {
+ return a + a + a + a;
+}
+// CHECK: @_ZN1A15noinline_methodEi({{.*}}) [[OPTNONE]]
+
+// 'optnone' wins over 'minsize'
+__attribute__((optnone))
+int A::minsize_method(int a) {
+ return a + a + a + a;
+}
+// CHECK: @_ZN1A14minsize_methodEi({{.*}}) [[OPTNONE]]
+
+
+// Test attribute 'optnone' on methods:
+// -- pure virtual functions
+// -- base virtual and derived virtual
+// -- base virtual but not derived virtual
+// -- optnone methods redefined in override
+
+// A method defined in override doesn't inherit the function attributes of the
+// superclass method.
+
+struct B {
+ virtual int pure_virtual(int a) = 0;
+ __attribute__((optnone))
+ virtual int pure_virtual_with_optnone(int a) = 0;
+
+ virtual int base(int a) {
+ return a + a + a + a;
+ }
+
+ __attribute__((optnone))
+ virtual int optnone_base(int a) {
+ return a + a + a + a;
+ }
+
+ __attribute__((optnone))
+ virtual int only_base_virtual(int a) {
+ return a + a;
+ }
+};
+
+struct C : public B {
+ __attribute__((optnone))
+ virtual int pure_virtual(int a) {
+ return a + a + a + a;
+ }
+
+ virtual int pure_virtual_with_optnone(int a) {
+ return a + a + a + a;
+ }
+
+ __attribute__((optnone))
+ virtual int base(int a) {
+ return a + a;
+ }
+
+ virtual int optnone_base(int a) {
+ return a + a;
+ }
+
+ int only_base_virtual(int a) {
+ return a + a + a + a;
+ }
+};
+
+int bar() {
+ C c;
+ int result;
+ result = c.pure_virtual(3);
+ result += c.pure_virtual_with_optnone(2);
+ result += c.base(5);
+ result += c.optnone_base(7);
+ result += c.only_base_virtual(9);
+ return result;
+}
+
+// CHECK: @_ZN1C12pure_virtualEi({{.*}}) {{.*}} [[OPTNONE]]
+// CHECK: @_ZN1C25pure_virtual_with_optnoneEi({{.*}}) {{.*}} [[NORMAL:#[0-9]+]]
+// CHECK: @_ZN1C4baseEi({{.*}}) {{.*}} [[OPTNONE]]
+// CHECK: @_ZN1C12optnone_baseEi({{.*}}) {{.*}} [[NORMAL]]
+// CHECK: @_ZN1C17only_base_virtualEi({{.*}}) {{.*}} [[NORMAL]]
+// CHECK: @_ZN1B4baseEi({{.*}}) {{.*}} [[NORMAL]]
+// CHECK: @_ZN1B12optnone_baseEi({{.*}}) {{.*}} [[OPTNONE]]
+// CHECK: @_ZN1B17only_base_virtualEi({{.*}}) {{.*}} [[OPTNONE]]
+
+
+// CHECK: attributes [[NORMAL]] =
+// CHECK-NOT: noinline
+// CHECK-NOT: optnone
+// CHECK: attributes [[OPTNONE]] = {{.*}} noinline {{.*}} optnone
diff --git a/src/llvm-project/clang/test/CodeGenCXX/optnone-def-decl.cpp b/src/llvm-project/clang/test/CodeGenCXX/optnone-def-decl.cpp
new file mode 100644
index 0000000..6e4e510
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/optnone-def-decl.cpp
@@ -0,0 +1,95 @@
+// RUN: %clang_cc1 %s -triple %itanium_abi_triple -fms-extensions -O2 -disable-llvm-passes -emit-llvm -o - | FileCheck %s
+
+// Test optnone on both function declarations and function definitions.
+// Verify also that we don't generate invalid IR functions with
+// both alwaysinline and noinline. (optnone implies noinline and wins
+// over alwaysinline, in all cases.)
+
+// Test optnone on extern declaration only.
+extern int decl_only(int a) __attribute__((optnone));
+
+// This function should be marked 'optnone'.
+int decl_only(int a) {
+ return a + a + a + a;
+}
+
+// CHECK: define {{.*}} @_Z9decl_onlyi({{.*}}) [[OPTNONE:#[0-9]+]]
+
+// Test optnone on definition but not extern declaration.
+extern int def_only(int a);
+
+__attribute__((optnone))
+int def_only(int a) {
+ return a + a + a + a;
+}
+
+// Function def_only is a optnone function and therefore it should not be
+// inlined inside 'user_of_def_only'.
+int user_of_def_only() {
+ return def_only(5);
+}
+
+// CHECK: define {{.*}} @_Z8def_onlyi({{.*}}) [[OPTNONE]]
+// CHECK: define {{.*}} @_Z16user_of_def_onlyv() [[NORMAL:#[0-9]+]]
+
+// Test optnone on both definition and declaration.
+extern int def_and_decl(int a) __attribute__((optnone));
+
+__attribute__((optnone))
+int def_and_decl(int a) {
+ return a + a + a + a;
+}
+
+// CHECK: define {{.*}} @_Z12def_and_decli({{.*}}) [[OPTNONE]]
+
+// Check that optnone wins over always_inline.
+
+// Test optnone on definition and always_inline on declaration.
+extern int always_inline_function(int a) __attribute__((always_inline));
+
+__attribute__((optnone))
+extern int always_inline_function(int a) {
+ return a + a + a + a;
+}
+// CHECK: define {{.*}} @_Z22always_inline_functioni({{.*}}) [[OPTNONE]]
+
+int user_of_always_inline_function() {
+ return always_inline_function(4);
+}
+
+// CHECK: define {{.*}} @_Z30user_of_always_inline_functionv() [[NORMAL]]
+
+// Test optnone on declaration and always_inline on definition.
+extern int optnone_function(int a) __attribute__((optnone));
+
+__attribute__((always_inline))
+int optnone_function(int a) {
+ return a + a + a + a;
+}
+// CHECK: define {{.*}} @_Z16optnone_functioni({{.*}}) [[OPTNONE]]
+
+int user_of_optnone_function() {
+ return optnone_function(4);
+}
+
+// CHECK: define {{.*}} @_Z24user_of_optnone_functionv() [[NORMAL]]
+
+// Test the combination of optnone with forceinline (optnone wins).
+extern __forceinline int forceinline_optnone_function(int a, int b);
+
+__attribute__((optnone))
+extern int forceinline_optnone_function(int a, int b) {
+ return a + b;
+}
+
+int user_of_forceinline_optnone_function() {
+ return forceinline_optnone_function(4,5);
+}
+
+// CHECK: @_Z36user_of_forceinline_optnone_functionv() [[NORMAL]]
+// CHECK: @_Z28forceinline_optnone_functionii({{.*}}) [[OPTNONE]]
+
+// CHECK: attributes [[OPTNONE]] = { noinline nounwind optnone {{.*}} }
+// CHECK: attributes [[NORMAL]] =
+// CHECK-NOT: noinline
+// CHECK-NOT: optnone
diff --git a/src/llvm-project/clang/test/CodeGenCXX/optnone-pragma-optimize-off.cpp b/src/llvm-project/clang/test/CodeGenCXX/optnone-pragma-optimize-off.cpp
new file mode 100644
index 0000000..d750c4c
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/optnone-pragma-optimize-off.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 %s -triple %itanium_abi_triple -O1 -disable-llvm-passes -emit-llvm -o - | FileCheck %s
+
+// Test the attributes for the lambda function contains 'optnone' as result of
+// the _Pragma("clang optimize off").
+
+_Pragma("clang optimize off")
+
+void foo(int p) {
+ auto lambda = [&p]() { ++p; };
+ lambda();
+ // CHECK: define {{.*}} @"_ZZ3fooiENK3$_0clEv"({{.*}}) #[[LAMBDA_ATR:[0-9]+]]
+}
+
+_Pragma("clang optimize on")
+
+// CHECK: attributes #[[LAMBDA_ATR]] = { {{.*}} optnone {{.*}} }
\ No newline at end of file
diff --git a/src/llvm-project/clang/test/CodeGenCXX/optnone-templates.cpp b/src/llvm-project/clang/test/CodeGenCXX/optnone-templates.cpp
new file mode 100644
index 0000000..7884fa3
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/optnone-templates.cpp
@@ -0,0 +1,104 @@
+// RUN: %clang_cc1 %s -triple %itanium_abi_triple -std=c++11 -disable-O0-optnone -emit-llvm -o - | FileCheck %s
+
+// Test optnone on template instantiations.
+
+//-- Effect of optnone on generic add template function.
+
+template <typename T> T template_normal(T a)
+{
+ return a + a;
+}
+
+template <typename T> __attribute__((optnone)) T template_optnone(T a)
+{
+ return a + a + a;
+}
+
+// This function should cause instantiations of each template, one marked
+// with the 'optnone' attribute.
+int container(int i)
+{
+ return template_normal<int>(i) + template_optnone<int>(i);
+}
+
+// CHECK: @_Z15template_normalIiET_S0_({{.*}}) [[NORMAL:#[0-9]+]]
+// CHECK: @_Z16template_optnoneIiET_S0_({{.*}}) [[OPTNONE:#[0-9]+]]
+
+
+//-- Effect of optnone on a partial specialization.
+// FIRST TEST: a method becomes marked with optnone in the specialization.
+
+template <typename T, typename U> class template_normal_base {
+public:
+ T method(T t, U u)
+ {
+ return t + static_cast<T>(u);
+ }
+};
+
+template <typename U> class template_normal_base<int, U>
+{
+public:
+ __attribute__((optnone)) int method (int t, U u)
+ {
+ return t - static_cast<int>(u);
+ }
+};
+
+// This function should cause an instantiation of the full template (whose
+// method is not marked optnone) and an instantiation of the partially
+// specialized template (whose method is marked optnone).
+void container2()
+{
+ int y = 2;
+ float z = 3.0;
+ template_normal_base<float, int> class_normal;
+ template_normal_base<int, float> class_optnone;
+ float r1 = class_normal.method(z, y);
+ float r2 = class_optnone.method(y, z);
+}
+
+// CHECK: @_ZN20template_normal_baseIfiE6methodEfi({{.*}}) [[NORMAL]]
+// CHECK: @_ZN20template_normal_baseIifE6methodEif({{.*}}) [[OPTNONE]]
+
+
+//-- Effect of optnone on a partial specialization.
+// SECOND TEST: a method loses optnone in the specialization.
+
+template <typename T, typename U> class template_optnone_base {
+public:
+ __attribute__((optnone)) T method(T t, U u)
+ {
+ return t + static_cast<T>(u);
+ }
+};
+
+template <typename U> class template_optnone_base<int, U>
+{
+public:
+ int method (int t, U u)
+ {
+ return t - static_cast<int>(u);
+ }
+};
+
+// This function should cause an instantiation of the full template (whose
+// method is marked optnone) and an instantiation of the partially
+// specialized template (whose method is not marked optnone).
+void container3()
+{
+ int y = 2;
+ float z = 3.0;
+ template_optnone_base<float, int> class_optnone;
+ template_optnone_base<int, float> class_normal;
+ float r1 = class_optnone.method(z, y);
+ float r2 = class_normal.method(y, z);
+}
+
+// CHECK: @_ZN21template_optnone_baseIfiE6methodEfi({{.*}}) [[OPTNONE]]
+// CHECK: @_ZN21template_optnone_baseIifE6methodEif({{.*}}) [[NORMAL]]
+
+
+// CHECK: attributes [[NORMAL]] =
+// CHECK-NOT: optnone
+// CHECK: attributes [[OPTNONE]] = {{.*}} optnone
diff --git a/src/llvm-project/clang/test/CodeGenCXX/overload-binop-implicitconvert.cpp b/src/llvm-project/clang/test/CodeGenCXX/overload-binop-implicitconvert.cpp
new file mode 100644
index 0000000..0eb7a06
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/overload-binop-implicitconvert.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 %s -emit-llvm-only
+class T
+{};
+
+void print(const char *t);
+
+T& operator<< (T& t,const char* c)
+{
+ print(c);
+ return t;
+}
+
+
+int main()
+{
+ T t;
+ print("foo");
+ t<<"foo";
+
+ return 0;
+}
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/override-bit-field-layout.cpp b/src/llvm-project/clang/test/CodeGenCXX/override-bit-field-layout.cpp
new file mode 100644
index 0000000..e84fcb0
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/override-bit-field-layout.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -w -fdump-record-layouts-simple -foverride-record-layout=%S/Inputs/override-bit-field-layout.layout %s | FileCheck %s
+
+// CHECK: Type: struct S1
+// CHECK: FieldOffsets: [0, 11]
+struct S1 {
+ short a : 3;
+ short b : 5;
+};
+
+// CHECK: Type: struct S2
+// CHECK: FieldOffsets: [64]
+struct S2 {
+ virtual ~S2() = default;
+ short a : 3;
+};
+
+void use_structs() {
+ S1 s1s[sizeof(S1)];
+ S2 s2s[sizeof(S2)];
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/override-layout-nameless-struct-union.cpp b/src/llvm-project/clang/test/CodeGenCXX/override-layout-nameless-struct-union.cpp
new file mode 100644
index 0000000..acc1ff7
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/override-layout-nameless-struct-union.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -w -fdump-record-layouts-simple -foverride-record-layout=%S/Inputs/override-layout-nameless-struct-union.layout %s | FileCheck %s
+
+// CHECK: Type: struct S
+// CHECK: Size:64
+// CHECK: Alignment:32
+// CHECK: FieldOffsets: [0, 32, 32]
+struct S {
+ short _s;
+//union {
+ int _su0;
+ char _su1;
+//};
+};
+
+// CHECK: Type: union U
+// CHECK: Size:96
+// CHECK: Alignment:32
+// CHECK: FieldOffsets: [0, 0, 32, 64, 68, 73]
+union U {
+ short _u;
+//struct {
+ char _us0;
+ int _us1;
+ unsigned _us20 : 4;
+ unsigned _us21 : 5;
+ unsigned _us22 : 6;
+//};
+};
+
+void use_structs() {
+ S ss[sizeof(S)];
+ U us[sizeof(U)];
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/override-layout-packed-base.cpp b/src/llvm-project/clang/test/CodeGenCXX/override-layout-packed-base.cpp
new file mode 100644
index 0000000..03255f2
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/override-layout-packed-base.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -triple i686-windows-msvc -w -fdump-record-layouts-simple -foverride-record-layout=%S/Inputs/override-layout-packed-base.layout %s | FileCheck %s
+
+//#pragma pack(push, 1)
+
+// CHECK: Type: class B<0>
+// CHECK: Size:40
+// CHECK: FieldOffsets: [0, 32]
+
+// CHECK: Type: class B<1>
+// CHECK: Size:40
+// CHECK: FieldOffsets: [0, 32]
+
+template<int I>
+class B {
+ int _b1;
+ char _b2;
+};
+
+// CHECK: Type: class C
+// CHECK: Size:88
+// CHECK: FieldOffsets: [80]
+
+class C : B<0>, B<1> {
+ char _c;
+};
+
+// CHECK: Type: class D
+// CHECK: Size:120
+// CHECK: FieldOffsets: [32]
+
+class D : virtual B<0>, virtual B<1> {
+ char _d;
+};
+
+//#pragma pack(pop)
+
+void use_structs() {
+ C cs[sizeof(C)];
+ D ds[sizeof(D)];
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/override-layout.cpp b/src/llvm-project/clang/test/CodeGenCXX/override-layout.cpp
new file mode 100644
index 0000000..a3c4bb4
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/override-layout.cpp
@@ -0,0 +1,77 @@
+// RUN: %clang_cc1 -w -fdump-record-layouts-simple %s > %t.layouts
+// RUN: %clang_cc1 -w -fdump-record-layouts-simple %s > %t.before
+// RUN: %clang_cc1 -w -DPACKED= -DALIGNED16= -fdump-record-layouts-simple -foverride-record-layout=%t.layouts %s > %t.after
+// RUN: diff -u %t.before %t.after
+// RUN: FileCheck %s < %t.after
+
+// If not explicitly disabled, set PACKED to the packed attribute.
+#ifndef PACKED
+# define PACKED __attribute__((packed))
+#endif
+
+struct Empty1 { };
+struct Empty2 { };
+
+// CHECK: Type: struct X0
+struct X0 : public Empty1 {
+ int x[6] PACKED;
+};
+
+// CHECK: Type: struct X1
+struct X1 : public X0, public Empty2 {
+ char x[13];
+ struct X0 y;
+} PACKED;
+
+// CHECK: Type: struct X2
+struct PACKED X2 : public X1, public X0, public Empty1 {
+ short x;
+ int y;
+};
+
+// CHECK: Type: struct X3
+struct PACKED X3 : virtual public X1, public X0 {
+ short x;
+ int y;
+};
+
+// CHECK: Type: struct X4
+struct PACKED X4 {
+ unsigned int a : 1;
+ unsigned int b : 1;
+ unsigned int c : 1;
+ unsigned int d : 1;
+ unsigned int e : 1;
+ unsigned int f : 1;
+ unsigned int g : 1;
+ unsigned int h : 1;
+ unsigned int i : 1;
+ unsigned int j : 1;
+ unsigned int k : 1;
+ unsigned int l : 1;
+ unsigned int m : 1;
+ unsigned int n : 1;
+ X4();
+};
+
+// CHECK: Type: struct X5
+struct PACKED X5 {
+ union {
+ long a;
+ long b;
+ };
+ short l;
+ short r;
+};
+
+void use_structs() {
+ X0 x0s[sizeof(X0)];
+ X1 x1s[sizeof(X1)];
+ X2 x2s[sizeof(X2)];
+ X3 x3s[sizeof(X3)];
+ X4 x4s[sizeof(X4)];
+ X5 x5s[sizeof(X5)];
+ x4s[1].a = 1;
+ x5s[1].a = 17;
+}
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/partial-destruction.cpp b/src/llvm-project/clang/test/CodeGenCXX/partial-destruction.cpp
new file mode 100644
index 0000000..a5a2f40
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/partial-destruction.cpp
@@ -0,0 +1,213 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - -fcxx-exceptions -fexceptions -std=c++03 | FileCheck %s -check-prefixes=CHECK,CHECKv03
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - -fcxx-exceptions -fexceptions -std=c++11 | FileCheck %s -check-prefixes=CHECK,CHECKv11
+
+// Test IR generation for partial destruction of aggregates.
+
+void opaque();
+
+// Initializer lists.
+namespace test0 {
+ struct A { A(int); A(); ~A(); void *v; };
+ void test() {
+ A as[10] = { 5, 7 };
+ opaque();
+ }
+ // CHECK-LABEL: define void @_ZN5test04testEv()
+ // CHECK-SAME: personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ // CHECK: [[AS:%.*]] = alloca [10 x [[A:%.*]]], align
+ // CHECK-NEXT: [[ENDVAR:%.*]] = alloca [[A]]*
+ // CHECK-NEXT: [[EXN:%.*]] = alloca i8*
+ // CHECK-NEXT: [[SEL:%.*]] = alloca i32
+
+ // Initialize.
+ // CHECK-NEXT: [[E_BEGIN:%.*]] = getelementptr inbounds [10 x [[A]]], [10 x [[A]]]* [[AS]], i64 0, i64 0
+ // CHECK-NEXT: store [[A]]* [[E_BEGIN]], [[A]]** [[ENDVAR]]
+ // CHECK-NEXT: invoke void @_ZN5test01AC1Ei([[A]]* [[E_BEGIN]], i32 5)
+ // CHECK: [[E1:%.*]] = getelementptr inbounds [[A]], [[A]]* [[E_BEGIN]], i64 1
+ // CHECK-NEXT: store [[A]]* [[E1]], [[A]]** [[ENDVAR]]
+ // CHECK-NEXT: invoke void @_ZN5test01AC1Ei([[A]]* [[E1]], i32 7)
+ // CHECK: [[E2:%.*]] = getelementptr inbounds [[A]], [[A]]* [[E1]], i64 1
+ // CHECK-NEXT: store [[A]]* [[E2]], [[A]]** [[ENDVAR]]
+ // CHECK-NEXT: [[E_END:%.*]] = getelementptr inbounds [[A]], [[A]]* [[E_BEGIN]], i64 10
+ // CHECK-NEXT: br label
+ // CHECK: [[E_CUR:%.*]] = phi [[A]]* [ [[E2]], {{%.*}} ], [ [[E_NEXT:%.*]], {{%.*}} ]
+ // CHECK-NEXT: invoke void @_ZN5test01AC1Ev([[A]]* [[E_CUR]])
+ // CHECK: [[E_NEXT]] = getelementptr inbounds [[A]], [[A]]* [[E_CUR]], i64 1
+ // CHECK-NEXT: store [[A]]* [[E_NEXT]], [[A]]** [[ENDVAR]]
+ // CHECK-NEXT: [[T0:%.*]] = icmp eq [[A]]* [[E_NEXT]], [[E_END]]
+ // CHECK-NEXT: br i1 [[T0]],
+
+ // Run.
+ // CHECK: invoke void @_Z6opaquev()
+
+ // Normal destroy.
+ // CHECK: [[ED_BEGIN:%.*]] = getelementptr inbounds [10 x [[A]]], [10 x [[A]]]* [[AS]], i32 0, i32 0
+ // CHECK-NEXT: [[ED_END:%.*]] = getelementptr inbounds [[A]], [[A]]* [[ED_BEGIN]], i64 10
+ // CHECK-NEXT: br label
+ // CHECK: [[ED_AFTER:%.*]] = phi [[A]]* [ [[ED_END]], {{%.*}} ], [ [[ED_CUR:%.*]], {{%.*}} ]
+ // CHECK-NEXT: [[ED_CUR]] = getelementptr inbounds [[A]], [[A]]* [[ED_AFTER]], i64 -1
+ // CHECKv03-NEXT: invoke void @_ZN5test01AD1Ev([[A]]* [[ED_CUR]])
+ // CHECKv11-NEXT: call void @_ZN5test01AD1Ev([[A]]* [[ED_CUR]])
+ // CHECK: [[T0:%.*]] = icmp eq [[A]]* [[ED_CUR]], [[ED_BEGIN]]
+ // CHECK-NEXT: br i1 [[T0]],
+ // CHECK: ret void
+
+ // Partial destroy for initialization.
+ // CHECK: landingpad { i8*, i32 }
+ // CHECK-NEXT: cleanup
+ // CHECK: [[PARTIAL_END:%.*]] = load [[A]]*, [[A]]** [[ENDVAR]]
+ // CHECK-NEXT: [[T0:%.*]] = icmp eq [[A]]* [[E_BEGIN]], [[PARTIAL_END]]
+ // CHECK-NEXT: br i1 [[T0]],
+ // CHECK: [[E_AFTER:%.*]] = phi [[A]]* [ [[PARTIAL_END]], {{%.*}} ], [ [[E_CUR:%.*]], {{%.*}} ]
+ // CHECK-NEXT: [[E_CUR]] = getelementptr inbounds [[A]], [[A]]* [[E_AFTER]], i64 -1
+ // CHECKv03-NEXT: invoke void @_ZN5test01AD1Ev([[A]]* [[E_CUR]])
+ // CHECKv11-NEXT: call void @_ZN5test01AD1Ev([[A]]* [[E_CUR]])
+ // CHECK: [[T0:%.*]] = icmp eq [[A]]* [[E_CUR]], [[E_BEGIN]]
+ // CHECK-NEXT: br i1 [[T0]],
+
+ // Primary EH destructor.
+ // CHECK: landingpad { i8*, i32 }
+ // CHECK-NEXT: cleanup
+ // CHECK: [[E0:%.*]] = getelementptr inbounds [10 x [[A]]], [10 x [[A]]]* [[AS]], i32 0, i32 0
+ // CHECK-NEXT: [[E_END:%.*]] = getelementptr inbounds [[A]], [[A]]* [[E0]], i64 10
+ // CHECK-NEXT: br label
+
+ // Partial destructor for primary normal destructor.
+ // FIXME: There's some really bad block ordering here which causes
+ // the partial destroy for the primary normal destructor to fall
+ // within the primary EH destructor.
+ // CHECKv03: landingpad { i8*, i32 }
+ // CHECKv03-NEXT: cleanup
+ // CHECKv03: [[T0:%.*]] = icmp eq [[A]]* [[ED_BEGIN]], [[ED_CUR]]
+ // CHECKv03-NEXT: br i1 [[T0]]
+ // CHECKv03: [[EDD_AFTER:%.*]] = phi [[A]]* [ [[ED_CUR]], {{%.*}} ], [ [[EDD_CUR:%.*]], {{%.*}} ]
+ // CHECKv03-NEXT: [[EDD_CUR]] = getelementptr inbounds [[A]], [[A]]* [[EDD_AFTER]], i64 -1
+ // CHECKv03-NEXT: invoke void @_ZN5test01AD1Ev([[A]]* [[EDD_CUR]])
+ // CHECKv03: [[T0:%.*]] = icmp eq [[A]]* [[EDD_CUR]], [[ED_BEGIN]]
+ // CHECKv03-NEXT: br i1 [[T0]]
+
+ // Back to the primary EH destructor.
+ // CHECK: [[E_AFTER:%.*]] = phi [[A]]* [ [[E_END]], {{%.*}} ], [ [[E_CUR:%.*]], {{%.*}} ]
+ // CHECK-NEXT: [[E_CUR]] = getelementptr inbounds [[A]], [[A]]* [[E_AFTER]], i64 -1
+ // CHECKv03-NEXT: invoke void @_ZN5test01AD1Ev([[A]]* [[E_CUR]])
+ // CHECKv11-NEXT: call void @_ZN5test01AD1Ev([[A]]* [[E_CUR]])
+ // CHECK: [[T0:%.*]] = icmp eq [[A]]* [[E_CUR]], [[E0]]
+ // CHECK-NEXT: br i1 [[T0]],
+
+}
+
+namespace test1 {
+ struct A { A(); A(int); ~A(); };
+ struct B { A x, y, z; int w; };
+
+ void test() {
+ B v = { 5, 6, 7, 8 };
+ }
+ // CHECK-LABEL: define void @_ZN5test14testEv()
+ // CHECK-SAME: personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ // CHECK: [[V:%.*]] = alloca [[B:%.*]], align 4
+ // CHECK-NEXT: alloca i8*
+ // CHECK-NEXT: alloca i32
+ // CHECK-NEXT: [[X:%.*]] = getelementptr inbounds [[B]], [[B]]* [[V]], i32 0, i32 0
+ // CHECK-NEXT: call void @_ZN5test11AC1Ei([[A:%.*]]* [[X]], i32 5)
+ // CHECK-NEXT: [[Y:%.*]] = getelementptr inbounds [[B]], [[B]]* [[V]], i32 0, i32 1
+ // CHECK-NEXT: invoke void @_ZN5test11AC1Ei([[A]]* [[Y]], i32 6)
+ // CHECK: [[Z:%.*]] = getelementptr inbounds [[B]], [[B]]* [[V]], i32 0, i32 2
+ // CHECK-NEXT: invoke void @_ZN5test11AC1Ei([[A]]* [[Z]], i32 7)
+ // CHECK: [[W:%.*]] = getelementptr inbounds [[B]], [[B]]* [[V]], i32 0, i32 3
+ // CHECK-NEXT: store i32 8, i32* [[W]], align 4
+ // CHECK-NEXT: call void @_ZN5test11BD1Ev([[B]]* [[V]])
+ // CHECK-NEXT: ret void
+
+ // FIXME: again, the block ordering is pretty bad here
+ // CHECK: landingpad { i8*, i32 }
+ // CHECK-NEXT: cleanup
+ // CHECK: landingpad { i8*, i32 }
+ // CHECK-NEXT: cleanup
+ // CHECKv03: invoke void @_ZN5test11AD1Ev([[A]]* [[Y]])
+ // CHECKv03: invoke void @_ZN5test11AD1Ev([[A]]* [[X]])
+ // CHECKv11: call void @_ZN5test11AD1Ev([[A]]* [[Y]])
+ // CHECKv11: call void @_ZN5test11AD1Ev([[A]]* [[X]])
+}
+
+namespace test2 {
+ struct A { A(); ~A(); };
+
+ void test() {
+ A v[4][7];
+
+ // CHECK-LABEL: define void @_ZN5test24testEv()
+ // CHECK-SAME: personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ // CHECK: [[V:%.*]] = alloca [4 x [7 x [[A:%.*]]]], align 1
+ // CHECK-NEXT: alloca i8*
+ // CHECK-NEXT: alloca i32
+
+ // Main initialization loop.
+ // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [4 x [7 x [[A]]]], [4 x [7 x [[A]]]]* [[V]], i32 0, i32 0, i32 0
+ // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]], [[A]]* [[BEGIN]], i64 28
+ // CHECK-NEXT: br label
+ // CHECK: [[CUR:%.*]] = phi [[A]]* [ [[BEGIN]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ]
+ // CHECK-NEXT: invoke void @_ZN5test21AC1Ev([[A]]* [[CUR]])
+ // CHECK: [[NEXT:%.*]] = getelementptr inbounds [[A]], [[A]]* [[CUR]], i64 1
+ // CHECK-NEXT: [[DONE:%.*]] = icmp eq [[A]]* [[NEXT]], [[END]]
+ // CHECK-NEXT: br i1 [[DONE]],
+
+ // Partial destruction landing pad.
+ // CHECK: landingpad { i8*, i32 }
+ // CHECK-NEXT: cleanup
+ // CHECK: [[EMPTY:%.*]] = icmp eq [[A]]* [[BEGIN]], [[CUR]]
+ // CHECK-NEXT: br i1 [[EMPTY]],
+ // CHECK: [[PAST:%.*]] = phi [[A]]* [ [[CUR]], {{%.*}} ], [ [[DEL:%.*]], {{%.*}} ]
+ // CHECK-NEXT: [[DEL]] = getelementptr inbounds [[A]], [[A]]* [[PAST]], i64 -1
+ // CHECKv03-NEXT: invoke void @_ZN5test21AD1Ev([[A]]* [[DEL]])
+ // CHECKv11-NEXT: call void @_ZN5test21AD1Ev([[A]]* [[DEL]])
+ // CHECK: [[T0:%.*]] = icmp eq [[A]]* [[DEL]], [[BEGIN]]
+ // CHECK-NEXT: br i1 [[T0]],
+ }
+
+}
+
+// PR10351
+namespace test3 {
+ struct A { A(); ~A(); void *p; };
+ struct B {
+ B() {}
+ A a;
+ };
+
+ B *test() {
+ return new B[10];
+ // invoke void @_ZN5test31BD1Ev(
+ }
+}
+
+namespace test4 {
+ struct A { A(unsigned i); ~A(); };
+ void test() {
+ A v[2][3] = { { A(0), A(1), A(2) }, { A(3), A(4), A(5) } };
+ }
+}
+// CHECK-LABEL: define void @_ZN5test44testEv()
+// CHECK: [[ARRAY:%.*]] = alloca [2 x [3 x [[A:%.*]]]], align
+// CHECK: [[A0:%.*]] = getelementptr inbounds [2 x [3 x [[A]]]], [2 x [3 x [[A]]]]* [[ARRAY]], i64 0, i64 0
+// CHECK-NEXT: store [3 x [[A]]]* [[A0]],
+// CHECK-NEXT: [[A00:%.*]] = getelementptr inbounds [3 x [[A]]], [3 x [[A]]]* [[A0]], i64 0, i64 0
+// CHECK-NEXT: store [[A]]* [[A00]],
+// CHECK-NEXT: invoke void @_ZN5test41AC1Ej([[A]]* [[A00]], i32 0)
+// CHECK: [[A01:%.*]] = getelementptr inbounds [[A]], [[A]]* [[A00]], i64 1
+// CHECK-NEXT: store [[A]]* [[A01]],
+// CHECK-NEXT: invoke void @_ZN5test41AC1Ej([[A]]* [[A01]], i32 1)
+// CHECK: [[A02:%.*]] = getelementptr inbounds [[A]], [[A]]* [[A01]], i64 1
+// CHECK-NEXT: store [[A]]* [[A02]],
+// CHECK-NEXT: invoke void @_ZN5test41AC1Ej([[A]]* [[A02]], i32 2)
+// CHECK: [[A1:%.*]] = getelementptr inbounds [3 x [[A]]], [3 x [[A]]]* [[A0]], i64 1
+// CHECK-NEXT: store [3 x [[A]]]* [[A1]],
+// CHECK-NEXT: [[A10:%.*]] = getelementptr inbounds [3 x [[A]]], [3 x [[A]]]* [[A1]], i64 0, i64 0
+// CHECK-NEXT: store [[A]]* [[A10]],
+// CHECK-NEXT: invoke void @_ZN5test41AC1Ej([[A]]* [[A10]], i32 3)
+// CHECK: [[A11:%.*]] = getelementptr inbounds [[A]], [[A]]* [[A10]], i64 1
+// CHECK-NEXT: store [[A]]* [[A11]],
+// CHECK-NEXT: invoke void @_ZN5test41AC1Ej([[A]]* [[A11]], i32 4)
+// CHECK: [[A12:%.*]] = getelementptr inbounds [[A]], [[A]]* [[A11]], i64 1
+// CHECK-NEXT: store [[A]]* [[A12]],
+// CHECK-NEXT: invoke void @_ZN5test41AC1Ej([[A]]* [[A12]], i32 5)
diff --git a/src/llvm-project/clang/test/CodeGenCXX/partial-init.cpp b/src/llvm-project/clang/test/CodeGenCXX/partial-init.cpp
new file mode 100644
index 0000000..cb94660
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/partial-init.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -std=c++11 -fcxx-exceptions -fexceptions -S -emit-llvm -o - %s | FileCheck %s
+
+namespace std {
+ struct string {
+ const char *p;
+ string(const char *s);
+ ~string();
+ };
+}
+
+struct Bar {
+ int a;
+};
+
+struct Foo {
+ std::string c;
+ Bar d[32];
+};
+
+static Foo table[] = {
+ { "blerg" },
+};
+
+// CHECK: define internal void @__cxx_global_var_init
+// CHECK: invoke {{.*}} @_ZNSt6stringC1EPKc(
+// CHECK-NOT: unreachable
+// CHECK: br label
diff --git a/src/llvm-project/clang/test/CodeGenCXX/pass-object-size.cpp b/src/llvm-project/clang/test/CodeGenCXX/pass-object-size.cpp
new file mode 100644
index 0000000..7fd8b59
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/pass-object-size.cpp
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -O0 %s -o - 2>&1 -std=c++11 | FileCheck %s
+
+int gi;
+
+namespace lambdas {
+// CHECK-LABEL: define void @_ZN7lambdas7LambdasEPc
+void Lambdas(char *ptr) {
+ auto L1 = [](void *const p __attribute__((pass_object_size(0)))) {
+ return __builtin_object_size(p, 0);
+ };
+
+ int i = 0;
+ auto L2 = [&i](void *const p __attribute__((pass_object_size(0)))) {
+ return __builtin_object_size(p, 0) + i;
+ };
+
+ // CHECK: @llvm.objectsize
+ gi = L1(ptr);
+ // CHECK: @llvm.objectsize
+ gi = L2(ptr);
+}
+
+// CHECK-DAG: define internal i64 @"_ZZN7lambdas7LambdasEPcENK3$_0clEPvU17pass_object_size0"
+// CHECK-NOT: call i64 @llvm.objectsize
+// CHECK-DAG: define internal i64 @"_ZZN7lambdas7LambdasEPcENK3$_1clEPvU17pass_object_size0"
+// CHECK-NOT: call i64 @llvm.objectsize
+}
+
+// This is here instead of in Sema/ because we need to check to make sure the
+// proper function is called. If it's not, we'll end up with assertion errors.
+namespace addrof {
+void OvlFoo(void *const __attribute__((pass_object_size(0)))) {}
+void OvlFoo(int *const) {}
+
+// CHECK: define void @_ZN6addrof4TestEv
+void Test() {
+ // Treating parens-only calls as though they were direct is consistent with
+ // how we handle other implicitly unaddressable functions (e.g. builtins).
+ // CHECK: call void @_ZN6addrof6OvlFooEPvU17pass_object_size0
+ (OvlFoo)(nullptr);
+
+ // CHECK: call void @_ZN6addrof6OvlFooEPi
+ (&OvlFoo)(nullptr);
+}
+}
+
+namespace delegate {
+ struct A {
+ A(void *const p __attribute__((pass_object_size(0))));
+ };
+ A::A(void *const p __attribute__((pass_object_size(0)))) {}
+ // Ensure that we forward the size through a delegating constructor call.
+ // CHECK: define void @_ZN8delegate1AC1EPvU17pass_object_size0({{[^,]*}}, i8*{{[^,]*}}, i64{{[^,]*}})
+ // CHECK: call void @_ZN8delegate1AC2EPvU17pass_object_size0({{[^,]*}}, i8*{{[^,]*}}, i64{{[^,]*}})
+}
+
+namespace variadic {
+// We had an issue where variadic member/operator calls with pass_object_size
+// would cause crashes.
+
+struct AsCtor {
+ AsCtor(const char *const c __attribute__((pass_object_size(0))), double a,
+ ...) {}
+};
+
+struct AsMember {
+ void bar(const char *const c __attribute__((pass_object_size(0))), double a,
+ ...) {}
+ void operator()(const char *const c __attribute__((pass_object_size(0))),
+ double a, ...) {}
+};
+
+// CHECK-LABEL: define void @_ZN8variadic4testEv()
+void test() {
+ // CHECK-RE: call{{[^@]+}}@_ZN8variadic6AsCtorC1EPKcU17pass_object_size0dz
+ AsCtor("a", 1.0);
+ // CHECK-RE: call{{[^@]+}}@_ZN8variadic8AsMember3barEPKcU17pass_object_size0dz
+ AsMember{}.bar("a", 1.0);
+ // CHECK-RE: call{{[^@]+}}@_ZN8variadic8AsMemberclEPKcU17pass_object_size0dz
+ AsMember{}("a", 1.0);
+}
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/personality.cpp b/src/llvm-project/clang/test/CodeGenCXX/personality.cpp
new file mode 100644
index 0000000..ce4bad3
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/personality.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -triple i686-unknown-linux-gnu -fexceptions -fcxx-exceptions -S -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-GNU
+// RUN: %clang_cc1 -triple i686-unknown-linux-gnu -fexceptions -fdwarf-exceptions -fcxx-exceptions -S -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-GNU-DWARF
+// RUN: %clang_cc1 -triple i686-unknown-linux-gnu -fexceptions -fseh-exceptions -fcxx-exceptions -S -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-GNU-SEH
+// RUN: %clang_cc1 -triple i686-unknown-linux-gnu -fexceptions -fsjlj-exceptions -fcxx-exceptions -S -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-GNU-SJLJ
+
+// RUN: %clang_cc1 -triple i686-unknown-windows-msvc -fexceptions -fcxx-exceptions -S -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-WIN
+// RUN: %clang_cc1 -triple i686-unknown-windows-msvc -D __SEH_EXCEPTIONS__ -fms-extensions -fexceptions -fcxx-exceptions -S -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-WIN-SEH-X86
+// RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -D __SEH_EXCEPTIONS__ -fms-extensions -fexceptions -fcxx-exceptions -S -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-WIN-SEH-X64
+
+// RUN: %clang_cc1 -triple i686-unknown-windows-gnu -fexceptions -fcxx-exceptions -S -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-GNU
+// RUN: %clang_cc1 -triple i686-unknown-windows-gnu -fexceptions -fdwarf-exceptions -fcxx-exceptions -S -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-GNU-DWARF
+// RUN: %clang_cc1 -triple i686-unknown-windows-gnu -fexceptions -fseh-exceptions -fcxx-exceptions -S -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-GNU-SEH
+// RUN: %clang_cc1 -triple i686-unknown-windows-gnu -fexceptions -fsjlj-exceptions -fcxx-exceptions -S -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-GNU-SJLJ
+
+extern void g();
+
+// CHECK-GNU: personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+// CHECK-GNU-DWARF: personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+// CHECK-GNU-SEH: personality i8* bitcast (i32 (...)* @__gxx_personality_seh0 to i8*)
+// CHECK-GNU-SJLJ: personality i8* bitcast (i32 (...)* @__gxx_personality_sj0 to i8*)
+
+// CHECK-WIN: personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
+
+void f() {
+ try {
+ g();
+ } catch (...) {
+ }
+}
+
+#if defined(__SEH_EXCEPTIONS__)
+// CHECK-WIN-SEH-X86: personality i8* bitcast (i32 (...)* @_except_handler3 to i8*)
+// CHECK-WIN-SEH-X64: personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
+
+void h(void) {
+ __try {
+ g();
+ } __finally {
+ }
+}
+#endif
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/pod-member-memcpys.cpp b/src/llvm-project/clang/test/CodeGenCXX/pod-member-memcpys.cpp
new file mode 100644
index 0000000..9facb8a
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/pod-member-memcpys.cpp
@@ -0,0 +1,268 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -std=c++03 -fexceptions -fcxx-exceptions -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple i386-apple-darwin10 -emit-llvm -std=c++03 -o - %s | FileCheck --check-prefix=CHECK-2 %s
+
+struct POD {
+ int w, x, y, z;
+};
+
+struct PODLike {
+ int w, x, y, z;
+ PODLike();
+ ~PODLike();
+};
+
+struct NonPOD {
+ NonPOD();
+ NonPOD(const NonPOD&);
+ NonPOD& operator=(const NonPOD&);
+};
+
+struct Basic {
+ int a, b, c, d;
+ NonPOD np;
+ int w, x, y, z;
+};
+
+struct PODMember {
+ int a, b, c, d;
+ POD p;
+ NonPOD np;
+ int w, x, y, z;
+};
+
+struct PODLikeMember {
+ int a, b, c, d;
+ PODLike pl;
+ NonPOD np;
+ int w, x, y, z;
+};
+
+struct ArrayMember {
+ int a, b, c, d;
+ int e[12];
+ NonPOD np;
+ int f[12];
+ int w, x, y, z;
+};
+
+struct VolatileMember {
+ int a, b, c, d;
+ volatile int v;
+ NonPOD np;
+ int w, x, y, z;
+};
+
+struct BitfieldMember {
+ int a, b, c, d;
+ NonPOD np;
+ int w : 6;
+ int x : 6;
+ int y : 6;
+ int z : 6;
+};
+
+struct BitfieldMember2 {
+ unsigned a : 1;
+ unsigned b, c, d;
+ NonPOD np;
+};
+
+struct BitfieldMember3 {
+ virtual void f();
+ int : 8;
+ int x : 1;
+ int y;
+};
+
+struct InnerClassMember {
+ struct {
+ int a, b, c, d;
+ } a;
+ int b, c, d, e;
+ NonPOD np;
+ int w, x, y, z;
+};
+
+struct ReferenceMember {
+ ReferenceMember(int &a, int &b, int &c, int &d)
+ : a(a), b(b), c(c), d(d) {}
+ int &a;
+ int &b;
+ NonPOD np;
+ int &c;
+ int &d;
+};
+
+struct __attribute__((packed)) PackedMembers {
+ char c;
+ NonPOD np;
+ int w, x, y, z;
+};
+
+// COPY-ASSIGNMENT OPERATORS:
+
+// Assignment operators are output in the order they're encountered.
+
+#define CALL_AO(T) void callAO##T(T& a, const T& b) { a = b; }
+
+CALL_AO(Basic)
+CALL_AO(PODMember)
+CALL_AO(PODLikeMember)
+CALL_AO(ArrayMember)
+CALL_AO(VolatileMember)
+CALL_AO(BitfieldMember)
+CALL_AO(InnerClassMember)
+CALL_AO(PackedMembers)
+
+// Basic copy-assignment:
+// CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.Basic* @_ZN5BasicaSERKS_(%struct.Basic* %this, %struct.Basic* dereferenceable({{[0-9]+}}))
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 16, i1 {{.*}})
+// CHECK: call dereferenceable({{[0-9]+}}) %struct.NonPOD* @_ZN6NonPODaSERKS_
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 16, i1 {{.*}})
+// CHECK: ret %struct.Basic*
+
+// PODMember copy-assignment:
+// CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.PODMember* @_ZN9PODMemberaSERKS_(%struct.PODMember* %this, %struct.PODMember* dereferenceable({{[0-9]+}}))
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 32, i1 {{.*}})
+// CHECK: call dereferenceable({{[0-9]+}}) %struct.NonPOD* @_ZN6NonPODaSERKS_
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 16, i1 {{.*}})
+// CHECK: ret %struct.PODMember*
+
+// PODLikeMember copy-assignment:
+// CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.PODLikeMember* @_ZN13PODLikeMemberaSERKS_(%struct.PODLikeMember* %this, %struct.PODLikeMember* dereferenceable({{[0-9]+}}))
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 32, i1 {{.*}})
+// CHECK: call dereferenceable({{[0-9]+}}) %struct.NonPOD* @_ZN6NonPODaSERKS_
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 16, i1 {{.*}})
+// CHECK: ret %struct.PODLikeMember*
+
+// ArrayMember copy-assignment:
+// CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.ArrayMember* @_ZN11ArrayMemberaSERKS_(%struct.ArrayMember* %this, %struct.ArrayMember* dereferenceable({{[0-9]+}}))
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 64, i1 {{.*}})
+// CHECK: call dereferenceable({{[0-9]+}}) %struct.NonPOD* @_ZN6NonPODaSERKS_
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 64, i1 {{.*}})
+// CHECK: ret %struct.ArrayMember*
+
+// VolatileMember copy-assignment:
+// CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.VolatileMember* @_ZN14VolatileMemberaSERKS_(%struct.VolatileMember* %this, %struct.VolatileMember* dereferenceable({{[0-9]+}}))
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 16, i1 {{.*}})
+// CHECK: load volatile i32, i32* {{.*}}, align 4
+// CHECK: store volatile i32 {{.*}}, align 4
+// CHECK: call dereferenceable({{[0-9]+}}) %struct.NonPOD* @_ZN6NonPODaSERKS_
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 16, i1 {{.*}})
+// CHECK: ret %struct.VolatileMember*
+
+// BitfieldMember copy-assignment:
+// CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.BitfieldMember* @_ZN14BitfieldMemberaSERKS_(%struct.BitfieldMember* %this, %struct.BitfieldMember* dereferenceable({{[0-9]+}}))
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 16, i1 {{.*}})
+// CHECK: call dereferenceable({{[0-9]+}}) %struct.NonPOD* @_ZN6NonPODaSERKS_
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 1 {{.*}} align 1 {{.*}}i64 3, i1 {{.*}})
+// CHECK: ret %struct.BitfieldMember*
+
+// InnerClass copy-assignment:
+// CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.InnerClassMember* @_ZN16InnerClassMemberaSERKS_(%struct.InnerClassMember* %this, %struct.InnerClassMember* dereferenceable({{[0-9]+}}))
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 32, i1 {{.*}})
+// CHECK: call dereferenceable({{[0-9]+}}) %struct.NonPOD* @_ZN6NonPODaSERKS_
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 16, i1 {{.*}})
+// CHECK: ret %struct.InnerClassMember*
+
+// PackedMembers copy-assignment:
+// CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.PackedMembers* @_ZN13PackedMembersaSERKS_(%struct.PackedMembers* %this, %struct.PackedMembers* dereferenceable({{[0-9]+}}))
+// CHECK: call dereferenceable({{[0-9]+}}) %struct.NonPOD* @_ZN6NonPODaSERKS_
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 1 {{.*}} align 1 {{.*}}i64 16, i1 {{.*}})
+// CHECK: ret %struct.PackedMembers*
+
+// COPY-CONSTRUCTORS:
+
+// Clang outputs copy-constructors in the reverse of the order that
+// copy-constructor calls are encountered. Add functions that call the copy
+// constructors of the classes above in reverse order here.
+
+#define CALL_CC(T) T callCC##T(const T& b) { return b; }
+
+CALL_CC(PackedMembers)
+// PackedMembers copy-assignment:
+// CHECK-LABEL: define linkonce_odr void @_ZN13PackedMembersC2ERKS_(%struct.PackedMembers* %this, %struct.PackedMembers* dereferenceable({{[0-9]+}}))
+// CHECK: call void @_ZN6NonPODC1ERKS_
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 1 {{.*}} align 1 {{.*}}i64 16, i1 {{.*}})
+// CHECK: ret void
+
+CALL_CC(BitfieldMember2)
+// BitfieldMember2 copy-constructor:
+// CHECK-2-LABEL: define linkonce_odr void @_ZN15BitfieldMember2C2ERKS_(%struct.BitfieldMember2* %this, %struct.BitfieldMember2* dereferenceable({{[0-9]+}}))
+// CHECK-2: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 16, i1 false)
+// CHECK-2: call void @_ZN6NonPODC1ERKS_
+// CHECK-2: ret void
+
+CALL_CC(BitfieldMember3)
+// BitfieldMember3 copy-constructor:
+// CHECK-LABEL: define linkonce_odr void @_ZN15BitfieldMember3C2ERKS_(%struct.BitfieldMember3* %this, %struct.BitfieldMember3* dereferenceable({{[0-9]+}}))
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 8 {{.*}} align 8 {{.*}}i64 8, i1 false)
+// CHECK: ret void
+
+CALL_CC(ReferenceMember)
+// ReferenceMember copy-constructor:
+// CHECK-LABEL: define linkonce_odr void @_ZN15ReferenceMemberC2ERKS_(%struct.ReferenceMember* %this, %struct.ReferenceMember* dereferenceable({{[0-9]+}}))
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 8 {{.*}} align 8 {{.*}}i64 16, i1 {{.*}})
+// CHECK: call void @_ZN6NonPODC1ERKS_
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 8 {{.*}} align 8 {{.*}}i64 16, i1 {{.*}})
+// CHECK: ret void
+
+CALL_CC(InnerClassMember)
+// InnerClass copy-constructor:
+// CHECK-LABEL: define linkonce_odr void @_ZN16InnerClassMemberC2ERKS_(%struct.InnerClassMember* %this, %struct.InnerClassMember* dereferenceable({{[0-9]+}}))
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 32, i1 {{.*}})
+// CHECK: call void @_ZN6NonPODC1ERKS_
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 16, i1 {{.*}})
+// CHECK: ret void
+
+CALL_CC(BitfieldMember)
+// BitfieldMember copy-constructor:
+// CHECK-LABEL: define linkonce_odr void @_ZN14BitfieldMemberC2ERKS_(%struct.BitfieldMember* %this, %struct.BitfieldMember* dereferenceable({{[0-9]+}}))
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 16, i1 {{.*}})
+// CHECK: call void @_ZN6NonPODC1ERKS_
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 1 {{.*}} align 1 {{.*}}i64 3, i1 {{.*}})
+// CHECK: ret void
+
+CALL_CC(VolatileMember)
+// VolatileMember copy-constructor:
+// CHECK-LABEL: define linkonce_odr void @_ZN14VolatileMemberC2ERKS_(%struct.VolatileMember* %this, %struct.VolatileMember* dereferenceable({{[0-9]+}}))
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 16, i1 {{.*}})
+// CHECK: load volatile i32, i32* {{.*}}, align 4
+// CHECK: store volatile i32 {{.*}}, align 4
+// CHECK: call void @_ZN6NonPODC1ERKS_
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 16, i1 {{.*}})
+// CHECK: ret void
+
+CALL_CC(ArrayMember)
+// ArrayMember copy-constructor:
+// CHECK-LABEL: define linkonce_odr void @_ZN11ArrayMemberC2ERKS_(%struct.ArrayMember* %this, %struct.ArrayMember* dereferenceable({{[0-9]+}}))
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 64, i1 {{.*}})
+// CHECK: call void @_ZN6NonPODC1ERKS_
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 64, i1 {{.*}})
+// CHECK: ret void
+
+CALL_CC(PODLikeMember)
+// PODLikeMember copy-constructor:
+// CHECK-LABEL: define linkonce_odr void @_ZN13PODLikeMemberC2ERKS_(%struct.PODLikeMember* %this, %struct.PODLikeMember* dereferenceable({{[0-9]+}}))
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 32, i1 {{.*}})
+// CHECK: invoke void @_ZN6NonPODC1ERKS_
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 16, i1 {{.*}})
+// CHECK: ret void
+// CHECK: landingpad
+// CHECK: invoke void @_ZN7PODLikeD1Ev
+
+CALL_CC(PODMember)
+// PODMember copy-constructor:
+// CHECK-LABEL: define linkonce_odr void @_ZN9PODMemberC2ERKS_(%struct.PODMember* %this, %struct.PODMember* dereferenceable({{[0-9]+}}))
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 32, i1 {{.*}})
+// CHECK: call void @_ZN6NonPODC1ERKS_
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 16, i1 {{.*}})
+// CHECK: ret void
+
+CALL_CC(Basic)
+// Basic copy-constructor:
+// CHECK-LABEL: define linkonce_odr void @_ZN5BasicC2ERKS_(%struct.Basic* %this, %struct.Basic* dereferenceable({{[0-9]+}}))
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 16, i1 {{.*}})
+// CHECK: call void @_ZN6NonPODC1ERKS_
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 16, i1 {{.*}})
+// CHECK: ret void
diff --git a/src/llvm-project/clang/test/CodeGenCXX/pointers-to-data-members.cpp b/src/llvm-project/clang/test/CodeGenCXX/pointers-to-data-members.cpp
new file mode 100644
index 0000000..fd1b9b8
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/pointers-to-data-members.cpp
@@ -0,0 +1,260 @@
+// 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
+
+struct A { int a; int b; };
+struct B { int b; };
+struct C : B, A { };
+
+// Zero init.
+namespace ZeroInit {
+ // CHECK-GLOBAL: @_ZN8ZeroInit1aE = global i64 -1
+ int A::* a;
+
+ // CHECK-GLOBAL: @_ZN8ZeroInit2aaE = global [2 x i64] [i64 -1, i64 -1]
+ int A::* aa[2];
+
+ // 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-GLOBAL: @_ZN8ZeroInit1bE = global i64 -1,
+ int A::* b = 0;
+
+ // CHECK-GLOBAL: @_ZN8ZeroInit2saE = internal global %struct.anon { i64 -1 }
+ struct {
+ int A::*a;
+ } sa;
+ void test_sa() { (void) sa; } // force emission
+
+ // 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-GLOBAL: @_ZN8ZeroInit2ssE = internal global %struct.anon.1 { %struct.anon.2 { i64 -1 } }
+ struct {
+ struct {
+ int A::*pa;
+ } s;
+ } ss;
+ void test_ss() { (void) ss; }
+
+ struct A {
+ int A::*a;
+ int b;
+ };
+
+ struct B {
+ A a[10];
+ char c;
+ int B::*b;
+ };
+
+ struct C : A, B { int j; };
+ // CHECK-GLOBAL: @_ZN8ZeroInit1cE = global {{%.*}} <{ %"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::B" { [10 x %"struct.ZeroInit::A"] [%"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::A" { i64 -1, i32 0 }], i8 0, i64 -1 }, i32 0, [4 x i8] zeroinitializer }>, align 8
+ C c;
+}
+
+// PR5674
+namespace PR5674 {
+ // CHECK-GLOBAL: @_ZN6PR56742pbE = global i64 4
+ int A::*pb = &A::b;
+}
+
+// Casts.
+namespace Casts {
+
+int A::*pa;
+int C::*pc;
+
+void f() {
+ // CHECK: store i64 -1, i64* @_ZN5Casts2paE
+ pa = 0;
+
+ // CHECK-NEXT: [[TMP:%.*]] = load i64, i64* @_ZN5Casts2paE, align 8
+ // CHECK-NEXT: [[ADJ:%.*]] = add nsw i64 [[TMP]], 4
+ // CHECK-NEXT: [[ISNULL:%.*]] = icmp eq i64 [[TMP]], -1
+ // CHECK-NEXT: [[RES:%.*]] = select i1 [[ISNULL]], i64 [[TMP]], i64 [[ADJ]]
+ // CHECK-NEXT: store i64 [[RES]], i64* @_ZN5Casts2pcE
+ pc = pa;
+
+ // CHECK-NEXT: [[TMP:%.*]] = load i64, i64* @_ZN5Casts2pcE, align 8
+ // CHECK-NEXT: [[ADJ:%.*]] = sub nsw i64 [[TMP]], 4
+ // CHECK-NEXT: [[ISNULL:%.*]] = icmp eq i64 [[TMP]], -1
+ // CHECK-NEXT: [[RES:%.*]] = select i1 [[ISNULL]], i64 [[TMP]], i64 [[ADJ]]
+ // CHECK-NEXT: store i64 [[RES]], i64* @_ZN5Casts2paE
+ pa = static_cast<int A::*>(pc);
+}
+
+}
+
+// Comparisons
+namespace Comparisons {
+ void f() {
+ int A::*a;
+
+ // CHECK: icmp ne i64 {{.*}}, -1
+ if (a) { }
+
+ // CHECK: icmp ne i64 {{.*}}, -1
+ if (a != 0) { }
+
+ // CHECK: icmp ne i64 -1, {{.*}}
+ if (0 != a) { }
+
+ // CHECK: icmp eq i64 {{.*}}, -1
+ if (a == 0) { }
+
+ // CHECK: icmp eq i64 -1, {{.*}}
+ if (0 == a) { }
+ }
+}
+
+namespace ValueInit {
+
+struct A {
+ int A::*a;
+
+ char c;
+
+ A();
+};
+
+// CHECK-LABEL: define void @_ZN9ValueInit1AC2Ev(%"struct.ValueInit::A"* %this) unnamed_addr
+// CHECK: store i64 -1, i64*
+// CHECK: ret void
+A::A() : a() {}
+
+}
+
+namespace VirtualBases {
+
+struct A {
+ char c;
+ int A::*i;
+};
+
+// CHECK-GLOBAL: @_ZN12VirtualBases1bE = global %"struct.VirtualBases::B" { i32 (...)** null, %"struct.VirtualBases::A" { i8 0, i64 -1 } }, align 8
+struct B : virtual A { };
+B b;
+
+// CHECK-GLOBAL: @_ZN12VirtualBases1cE = global %"struct.VirtualBases::C" { i32 (...)** null, i64 -1, %"struct.VirtualBases::A" { i8 0, i64 -1 } }, align 8
+struct C : virtual A { int A::*i; };
+C c;
+
+// CHECK-GLOBAL: @_ZN12VirtualBases1dE = global %"struct.VirtualBases::D" { %"struct.VirtualBases::C.base" { i32 (...)** null, i64 -1 }, i64 -1, %"struct.VirtualBases::A" { i8 0, i64 -1 } }, align 8
+struct D : C { int A::*i; };
+D d;
+
+}
+
+namespace Test1 {
+
+// Don't crash when A contains a bit-field.
+struct A {
+ int A::* a;
+ int b : 10;
+};
+A a;
+
+}
+
+namespace BoolPtrToMember {
+ struct X {
+ bool member;
+ };
+
+ // CHECK-LABEL: define dereferenceable({{[0-9]+}}) i8* @_ZN15BoolPtrToMember1fERNS_1XEMS0_b
+ bool &f(X &x, bool X::*member) {
+ // CHECK: {{bitcast.* to i8\*}}
+ // CHECK-NEXT: getelementptr inbounds i8, i8*
+ // CHECK-NEXT: ret i8*
+ 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 %"struct.test4::D" { %"struct.test4::C.base" zeroinitializer, i32* null, %"struct.test4::B.base" { i32 (...)** null, i64 -1 }, %"struct.test4::A" zeroinitializer }, align 8
+ D d;
+}
+
+namespace PR11487 {
+ union U
+ {
+ int U::* mptr;
+ char x[16];
+ } x;
+ // CHECK-GLOBAL: @_ZN7PR114871xE = global %"union.PR11487::U" { i64 -1, [8 x i8] zeroinitializer }, align 8
+
+}
+
+namespace PR13097 {
+ struct X { int x; X(const X&); };
+ struct A {
+ int qq;
+ X x;
+ };
+ A f();
+ X g() { return f().*&A::x; }
+ // CHECK-LABEL: define void @_ZN7PR130971gEv
+ // CHECK: call void @_ZN7PR130971fEv
+ // CHECK-NOT: memcpy
+ // CHECK: call void @_ZN7PR130971XC1ERKS0_
+}
+
+namespace PR21089 {
+struct A {
+ bool : 1;
+ int A::*x;
+ bool y;
+ A();
+};
+struct B : A {
+};
+B b;
+// CHECK-GLOBAL: @_ZN7PR210891bE = global %"struct.PR21089::B" { %"struct.PR21089::A.base" <{ i8 0, [7 x i8] zeroinitializer, i64 -1, i8 0 }>, [7 x i8] zeroinitializer }, align 8
+}
+
+namespace PR21282 {
+union U {
+ int U::*x;
+ long y[2];
+};
+U u;
+// CHECK-GLOBAL: @_ZN7PR212821uE = global %"union.PR21282::U" { i64 -1, [8 x i8] zeroinitializer }, align 8
+}
+
+namespace FlexibleArrayMember {
+struct S {
+ int S::*x[];
+};
+S s;
+// CHECK-GLOBAL: @_ZN19FlexibleArrayMember1sE = global %"struct.FlexibleArrayMember::S" zeroinitializer, align 8
+}
+
+namespace IndirectPDM {
+union U {
+ union {
+ int U::*m;
+ };
+};
+U u;
+// CHECK-GLOBAL: @_ZN11IndirectPDM1uE = global %"union.IndirectPDM::U" { %union.anon { i64 -1 } }, align 8
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/poly-unsigned.cpp b/src/llvm-project/clang/test/CodeGenCXX/poly-unsigned.cpp
new file mode 100644
index 0000000..e2ab430
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/poly-unsigned.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple arm64-apple-ios -target-feature +neon -ffreestanding -S -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-UNSIGNED-POLY %s
+// RUN: %clang_cc1 -triple arm64-linux-gnu -target-feature +neon -ffreestanding -S -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-UNSIGNED-POLY %s
+// RUN: %clang_cc1 -triple armv7-apple-ios -ffreestanding -target-cpu cortex-a8 -S -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-SIGNED-POLY %s
+
+#include <arm_neon.h>
+
+// Polynomial types really should be universally unsigned, otherwise casting
+// (say) poly8_t "x^7" to poly16_t would change it to "x^15 + x^14 + ... +
+// x^7". Unfortunately 32-bit ARM ended up in a slightly delicate ABI situation
+// so for now it got that wrong.
+
+poly16_t test_poly8(poly8_t pIn) {
+// CHECK-UNSIGNED-POLY: @_Z10test_poly8h
+// CHECK-UNSIGNED-POLY: zext i8 {{.*}} to i16
+
+// CHECK-SIGNED-POLY: @_Z10test_poly8a
+// CHECK-SIGNED-POLY: sext i8 {{.*}} to i16
+
+ return pIn;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/powerpc-byval.cpp b/src/llvm-project/clang/test/CodeGenCXX/powerpc-byval.cpp
new file mode 100644
index 0000000..ff87618
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/powerpc-byval.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=powerpc-unknown-linux | FileCheck %s
+
+struct S {
+ S();
+ ~S();
+};
+
+void byval(S one, S two) {
+ one = two;
+}
+
+// CHECK: define void @_Z5byval1SS_(%struct.S* %one, %struct.S* %two)
diff --git a/src/llvm-project/clang/test/CodeGenCXX/pr11797.cpp b/src/llvm-project/clang/test/CodeGenCXX/pr11797.cpp
new file mode 100644
index 0000000..3767b1d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/pr11797.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 %s -fvisibility hidden -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %s
+
+namespace std __attribute__ ((__visibility__ ("default"))) {}
+#pragma GCC visibility push(default)
+void foo() {
+}
+#pragma GCC visibility pop
+// CHECK-LABEL: define {{.*}}void @_Z3foov()
diff --git a/src/llvm-project/clang/test/CodeGenCXX/pr12104.cpp b/src/llvm-project/clang/test/CodeGenCXX/pr12104.cpp
new file mode 100644
index 0000000..560ffbe
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/pr12104.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -include %S/pr12104.h %s -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -x c++ -triple %itanium_abi_triple -emit-pch -o %t %S/pr12104.h
+// RUN: %clang_cc1 -include-pch %t %s -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %s
+
+template struct Patch<1>;
+
+// CHECK: _ZN5PatchILi1EE11no_neighborE
diff --git a/src/llvm-project/clang/test/CodeGenCXX/pr12104.h b/src/llvm-project/clang/test/CodeGenCXX/pr12104.h
new file mode 100644
index 0000000..f3e9363
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/pr12104.h
@@ -0,0 +1,9 @@
+template <int dimm> struct Patch {
+ static const unsigned int no_neighbor = 1;
+};
+template <int dim>
+const unsigned int Patch<dim>::no_neighbor;
+void f(const unsigned int);
+void g() {
+ f(Patch<1>::no_neighbor);
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/pr12251.cpp b/src/llvm-project/clang/test/CodeGenCXX/pr12251.cpp
new file mode 100644
index 0000000..49e61ca
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/pr12251.cpp
@@ -0,0 +1,145 @@
+// RUN: %clang_cc1 %s -triple i386-unknown-unknown -emit-llvm -O1 -relaxed-aliasing -fstrict-enums -std=c++11 -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple i386-unknown-unknown -emit-llvm -O1 -relaxed-aliasing -std=c++11 -o - | FileCheck --check-prefix=NO-STRICT-ENUMS %s
+
+bool f(bool *x) {
+ return *x;
+}
+// CHECK-LABEL: define zeroext i1 @_Z1fPb
+// CHECK: load i8, i8* %{{[^ ]*}}, align 1, !range [[RANGE_i8_0_2:![^ ]*]]
+
+// Only enum-tests follow. Ensure that after the bool test, no further range
+// metadata shows up when strict enums are disabled.
+// NO-STRICT-ENUMS-LABEL: define zeroext i1 @_Z1fPb
+// NO-STRICT-ENUMS: load i8, i8* %{{[^ ]*}}, align 1, !range
+// NO-STRICT-ENUMS-NOT: !range
+
+enum e1 { };
+e1 g1(e1 *x) {
+ return *x;
+}
+// CHECK-LABEL: define i32 @_Z2g1P2e1
+// CHECK: ret i32 0
+
+enum e2 { e2_a = 0 };
+e2 g2(e2 *x) {
+ return *x;
+}
+// CHECK-LABEL: define i32 @_Z2g2P2e2
+// CHECK: ret i32 0
+
+enum e3 { e3_a = 16 };
+e3 g3(e3 *x) {
+ return *x;
+}
+// CHECK-LABEL: define i32 @_Z2g3P2e3
+// CHECK: load i32, i32* %x, align 4, !range [[RANGE_i32_0_32:![^ ]*]]
+
+enum e4 { e4_a = -16};
+e4 g4(e4 *x) {
+ return *x;
+}
+// CHECK-LABEL: define i32 @_Z2g4P2e4
+// CHECK: load i32, i32* %x, align 4, !range [[RANGE_i32_m16_16:![^ ]*]]
+
+enum e5 { e5_a = -16, e5_b = 16};
+e5 g5(e5 *x) {
+ return *x;
+}
+// CHECK-LABEL: define i32 @_Z2g5P2e5
+// CHECK: load i32, i32* %x, align 4, !range [[RANGE_i32_m32_32:![^ ]*]]
+
+enum e6 { e6_a = -1 };
+e6 g6(e6 *x) {
+ return *x;
+}
+// CHECK-LABEL: define i32 @_Z2g6P2e6
+// CHECK: load i32, i32* %x, align 4, !range [[RANGE_i32_m1_1:![^ ]*]]
+
+enum e7 { e7_a = -16, e7_b = 2};
+e7 g7(e7 *x) {
+ return *x;
+}
+// CHECK-LABEL: define i32 @_Z2g7P2e7
+// CHECK: load i32, i32* %x, align 4, !range [[RANGE_i32_m16_16]]
+
+enum e8 { e8_a = -17};
+e8 g8(e8 *x) {
+ return *x;
+}
+// CHECK-LABEL: define i32 @_Z2g8P2e8
+// CHECK: load i32, i32* %x, align 4, !range [[RANGE_i32_m32_32:![^ ]*]]
+
+enum e9 { e9_a = 17};
+e9 g9(e9 *x) {
+ return *x;
+}
+// CHECK-LABEL: define i32 @_Z2g9P2e9
+// CHECK: load i32, i32* %x, align 4, !range [[RANGE_i32_0_32]]
+
+enum e10 { e10_a = -16, e10_b = 32};
+e10 g10(e10 *x) {
+ return *x;
+}
+// CHECK-LABEL: define i32 @_Z3g10P3e10
+// CHECK: load i32, i32* %x, align 4, !range [[RANGE_i32_m64_64:![^ ]*]]
+
+enum e11 {e11_a = 4294967296 };
+enum e11 g11(enum e11 *x) {
+ return *x;
+}
+// CHECK-LABEL: define i64 @_Z3g11P3e11
+// CHECK: load i64, i64* %x, align {{[84]}}, !range [[RANGE_i64_0_2pow33:![^ ]*]]
+
+enum e12 {e12_a = 9223372036854775808U };
+enum e12 g12(enum e12 *x) {
+ return *x;
+}
+// CHECK-LABEL: define i64 @_Z3g12P3e12
+// CHECK: load i64, i64* %x, align {{[84]}}
+// CHECK-NOT: range
+// CHECK: ret
+
+enum e13 : char {e13_a = -1 };
+e13 g13(e13 *x) {
+ return *x;
+}
+// CHECK-LABEL: define signext i8 @_Z3g13P3e13
+// CHECK: load i8, i8* %x, align 1
+// CHECK-NOT: range
+// CHECK: ret
+
+enum class e14 {e14_a = 1};
+e14 g14(e14 *x) {
+ return *x;
+}
+// CHECK-LABEL: define i32 @_Z3g14P3e14
+// CHECK: load i32, i32* %x, align 4
+// CHECK-NOT: range
+// CHECK: ret
+
+enum e15 { e15_a = 2147483648 };
+e15 g15(e15 *x) {
+ return *x;
+}
+// CHECK-LABEL: define i32 @_Z3g15P3e15
+// CHECK: load i32, i32* %x, align 4
+// CHECK-NOT: range
+// CHECK: ret
+
+enum e16 { e16_a = -2147483648 };
+e16 g16(e16 *x) {
+ return *x;
+}
+// CHECK-LABEL: define i32 @_Z3g16P3e16
+// CHECK: load i32, i32* %x, align 4
+// CHECK-NOT: range
+// CHECK: ret
+
+
+// CHECK: [[RANGE_i8_0_2]] = !{i8 0, i8 2}
+// CHECK: [[RANGE_i32_0_32]] = !{i32 0, i32 32}
+// CHECK: [[RANGE_i32_m16_16]] = !{i32 -16, i32 16}
+// CHECK: [[RANGE_i32_m32_32]] = !{i32 -32, i32 32}
+// CHECK: [[RANGE_i32_m1_1]] = !{i32 -1, i32 1}
+// CHECK: [[RANGE_i32_m64_64]] = !{i32 -64, i32 64}
+// CHECK: [[RANGE_i64_0_2pow33]] = !{i64 0, i64 8589934592}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/pr13396.cpp b/src/llvm-project/clang/test/CodeGenCXX/pr13396.cpp
new file mode 100644
index 0000000..e41dd39
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/pr13396.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu %s -emit-llvm -o - | FileCheck %s
+struct foo {
+ template<typename T>
+ __attribute__ ((regparm (3))) foo(T x) {}
+ __attribute__ ((regparm (3))) foo();
+ __attribute__ ((regparm (3))) ~foo();
+};
+
+foo::foo() {
+ // CHECK-LABEL: define void @_ZN3fooC2Ev(%struct.foo* inreg %this)
+ // CHECK-LABEL: define void @_ZN3fooC1Ev(%struct.foo* inreg %this)
+}
+
+foo::~foo() {
+ // CHECK-LABEL: define void @_ZN3fooD2Ev(%struct.foo* inreg %this)
+ // CHECK-LABEL: define void @_ZN3fooD1Ev(%struct.foo* inreg %this)
+}
+
+void dummy() {
+ // FIXME: how can we explicitly instantiate a template constructor? Gcc and
+ // older clangs accept:
+ // template foo::foo(int x);
+ foo x(10);
+ // CHECK-LABEL: define linkonce_odr void @_ZN3fooC1IiEET_(%struct.foo* inreg %this, i32 inreg %x)
+ // CHECK-LABEL: define linkonce_odr void @_ZN3fooC2IiEET_(%struct.foo* inreg %this, i32 inreg %x)
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/pr15753.cpp b/src/llvm-project/clang/test/CodeGenCXX/pr15753.cpp
new file mode 100644
index 0000000..fd2000b
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/pr15753.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
+
+template <typename T> static int Foo(T t);
+template <typename T>
+int Foo(T t) {
+ return t;
+}
+template<> int Foo<int>(int i) {
+ return i;
+}
+
+// CHECK-NOT: define
diff --git a/src/llvm-project/clang/test/CodeGenCXX/pr18635.cpp b/src/llvm-project/clang/test/CodeGenCXX/pr18635.cpp
new file mode 100644
index 0000000..94b5e45
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/pr18635.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -emit-llvm -std=c++11 -triple x86_64-pc-linux-gnu -o- %s | FileCheck %s
+
+// Global @x:
+// CHECK: [[X_GLOBAL:@[^ ]+]]{{.*}}thread_local global
+
+// returned somewhere in TLS wrapper:
+// CHECK: ret{{.*}}[[X_GLOBAL]]
+
+template <typename T> class unique_ptr {
+ template <typename F, typename S> struct pair {
+ F first;
+ S second;
+ };
+ pair<T *, int> data;
+public:
+ constexpr unique_ptr() noexcept : data() {}
+ explicit unique_ptr(T *p) noexcept : data() {}
+};
+
+thread_local unique_ptr<int> x;
+int main() { x = unique_ptr<int>(new int(5)); }
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/pr18661.cpp b/src/llvm-project/clang/test/CodeGenCXX/pr18661.cpp
new file mode 100644
index 0000000..65ffd6f
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/pr18661.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 %s -triple %itanium_abi_triple -fcxx-exceptions -fms-extensions -emit-llvm -o - | FileCheck %s
+
+extern "C" {
+ void f();
+
+ // In MS mode we don't validate the exception specification.
+ void f() throw() {
+ }
+}
+
+// PR18661: Clang would fail to emit function definition with mismatching
+// exception specification, even though it was just treated as a warning.
+
+// CHECK: define {{.*}}void @f()
diff --git a/src/llvm-project/clang/test/CodeGenCXX/pr18962.cpp b/src/llvm-project/clang/test/CodeGenCXX/pr18962.cpp
new file mode 100644
index 0000000..9e6ef16
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/pr18962.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -triple i686-linux-gnu %s -emit-llvm -o - | FileCheck %s
+
+class A {
+ // append has to have the same prototype as fn1 to tickle the bug.
+ void (*append)(A *);
+};
+
+class B {};
+class D;
+
+// C has to be non-C++98 POD with available tail padding, making the LLVM base
+// type differ from the complete LLVM type.
+class C {
+ // This member creates a circular LLVM type reference to %class.D.
+ D *m_group;
+ B changeListeners;
+};
+class D : C {};
+
+void fn1(A *p1) {
+}
+
+void
+fn2(C *) {
+}
+
+// We end up using an opaque type for 'append' to avoid circular references.
+// CHECK: %class.A = type { {}* }
+// CHECK: %class.C = type <{ %class.D*, %class.B, [3 x i8] }>
+// CHECK: %class.D = type { %class.C.base, [3 x i8] }
+// CHECK: %class.C.base = type <{ %class.D*, %class.B }>
+// CHECK: %class.B = type { i8 }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/pr20719.cpp b/src/llvm-project/clang/test/CodeGenCXX/pr20719.cpp
new file mode 100644
index 0000000..79fdd74
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/pr20719.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -triple i686-windows-msvc -emit-llvm -std=c++11 -o - %s | FileCheck %s
+
+// Make sure that we emit H's constructor twice: once with the first lambda
+// inside of 'lep' and again with the second lambda inside of 'lep'.
+// CHECK-DAG: @"??0?$H@V<lambda_1>@?0???$lep@X@@YAXXZ@@@QAE@XZ"
+// CHECK-DAG: @"??0?$H@V<lambda_2>@?0???$lep@X@@YAXXZ@@@QAE@XZ"
+
+template <typename>
+struct H {
+ H() {}
+};
+
+template <typename Fx>
+int K_void(const Fx &) {
+ H<Fx> callee;
+ return 0;
+}
+template <typename Fx>
+int K_int(const Fx &) {
+ H<Fx> callee;
+ return 0;
+}
+
+struct pair {
+ pair(int, int);
+};
+
+struct E1;
+
+template <typename>
+void lep() {
+ pair x(K_void([] {}), K_int([] {}));
+}
+
+auto z = lep<void>;
diff --git a/src/llvm-project/clang/test/CodeGenCXX/pr20897.cpp b/src/llvm-project/clang/test/CodeGenCXX/pr20897.cpp
new file mode 100644
index 0000000..73995fc
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/pr20897.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -triple i686-windows-msvc -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s | FileCheck %s
+struct Base {};
+
+// __declspec(dllexport) causes us to export the implicit constructor.
+struct __declspec(dllexport) Derived : virtual Base {
+// CHECK-LABEL: define weak_odr dso_local dllexport x86_thiscallcc %struct.Derived* @"??0Derived@@QAE@ABU0@@Z"
+// CHECK: %[[this:.*]] = load %struct.Derived*, %struct.Derived** {{.*}}
+// CHECK-NEXT: store %struct.Derived* %[[this]], %struct.Derived** %[[retval:.*]]
+// CHECK: %[[dest_a_gep:.*]] = getelementptr inbounds %struct.Derived, %struct.Derived* %[[this]], i32 0, i32 1
+// CHECK-NEXT: %[[src_load:.*]] = load %struct.Derived*, %struct.Derived** {{.*}}
+// CHECK-NEXT: %[[src_a_gep:.*]] = getelementptr inbounds %struct.Derived, %struct.Derived* %[[src_load:.*]], i32 0, i32 1
+// CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %[[dest_a_gep]], i8* align 4 %[[src_a_gep]], i64 1, i1 false)
+// CHECK-NEXT: %[[dest_this:.*]] = load %struct.Derived*, %struct.Derived** %[[retval]]
+// CHECK-NEXT: ret %struct.Derived* %[[dest_this]]
+ bool a : 1;
+ bool b : 1;
+};
+
+// __declspec(dllexport) causes us to export the implicit copy constructor.
+struct __declspec(dllexport) Derived2 : virtual Base {
+// CHECK-LABEL: define weak_odr dso_local dllexport x86_thiscallcc %struct.Derived2* @"??0Derived2@@QAE@ABU0@@Z"
+// CHECK: %[[this:.*]] = load %struct.Derived2*, %struct.Derived2** {{.*}}
+// CHECK-NEXT: store %struct.Derived2* %[[this]], %struct.Derived2** %[[retval:.*]]
+// CHECK: %[[dest_a_gep:.*]] = getelementptr inbounds %struct.Derived2, %struct.Derived2* %[[this]], i32 0, i32 1
+// CHECK-NEXT: %[[src_load:.*]] = load %struct.Derived2*, %struct.Derived2** {{.*}}
+// CHECK-NEXT: %[[src_a_gep:.*]] = getelementptr inbounds %struct.Derived2, %struct.Derived2* %[[src_load:.*]], i32 0, i32 1
+// CHECK-NEXT: %[[dest_a_bitcast:.*]] = bitcast [1 x i32]* %[[dest_a_gep]] to i8*
+// CHECK-NEXT: %[[src_a_bitcast:.*]] = bitcast [1 x i32]* %[[src_a_gep]] to i8*
+// CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %[[dest_a_bitcast]], i8* align 4 %[[src_a_bitcast]], i32 4, i1 false)
+// CHECK-NEXT: %[[dest_this:.*]] = load %struct.Derived2*, %struct.Derived2** %[[retval]]
+// CHECK-NEXT: ret %struct.Derived2* %[[dest_this]]
+ int Array[1];
+};
diff --git a/src/llvm-project/clang/test/CodeGenCXX/pr21989.cpp b/src/llvm-project/clang/test/CodeGenCXX/pr21989.cpp
new file mode 100644
index 0000000..0b9bccb
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/pr21989.cpp
@@ -0,0 +1,9 @@
+// REQUIRES: asserts
+// RUN: not %clang_cc1 -emit-llvm -triple %itanium_abi_triple -o - %s 2>&1 | FileCheck %s
+
+struct {
+ void __attribute__((used)) f() {}
+};
+// CHECK: 2 errors generated.
+
+// Emit the errors, but don't assert.
diff --git a/src/llvm-project/clang/test/CodeGenCXX/pr24097.cpp b/src/llvm-project/clang/test/CodeGenCXX/pr24097.cpp
new file mode 100644
index 0000000..cdf78d2
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/pr24097.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 %s -triple=x86_64-pc-linux -fvisibility hidden -emit-llvm -O1 -disable-llvm-passes -o - | FileCheck %s
+
+struct Filter {
+ virtual void Foo();
+};
+struct Sender {
+ virtual bool Send();
+};
+struct SyncMessageFilter : public Filter, public Sender {
+ bool Send();
+};
+struct TestSyncMessageFilter : public SyncMessageFilter {
+};
+void bar() {
+ TestSyncMessageFilter f;
+ f.Send();
+}
+
+// Test that it is not hidden
+// CHECK: define available_externally zeroext i1 @_ZThn8_N17SyncMessageFilter4SendEv
diff --git a/src/llvm-project/clang/test/CodeGenCXX/pr27030.cpp b/src/llvm-project/clang/test/CodeGenCXX/pr27030.cpp
new file mode 100644
index 0000000..ce83c89
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/pr27030.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -emit-llvm -triple=i386-pc-win32 %s -o - | FileCheck %s
+struct A {};
+struct B : A {};
+extern "C" {
+extern int B::*a;
+void test1() { (int A::*)(a); }
+}
+// CHECK-LABEL: define dso_local void @test1(
+// CHECK: %[[load:.*]] = load i32, i32* @a
+// CHECK: %[[memptr_cmp:.*]] = icmp ne i32 %[[load]], -1
+// CHECK: br i1 %[[memptr_cmp]]
+
+// CHECK: %[[adj:.*]] = sub nsw i32 %[[load]], 0
+// CHECK: %[[nv_adj:.*]] = select i1 true, i32 %[[adj]], i32 0
+
+// CHECK: %[[memptr_converted:.*]] = phi i32 [ -1, {{.*}} ], [ %[[nv_adj]], {{.*}} ]
diff --git a/src/llvm-project/clang/test/CodeGenCXX/pr28360.cpp b/src/llvm-project/clang/test/CodeGenCXX/pr28360.cpp
new file mode 100644
index 0000000..6bf2ea7
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/pr28360.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple i686-pc-win32 | FileCheck %s
+struct A {
+ void Foo();
+ void Foo(int);
+};
+
+using MpTy = void (A::*)();
+
+void Bar(const MpTy &);
+
+void Baz() { Bar(&A::Foo); }
+
+// CHECK-LABEL: define dso_local void @"?Baz@@YAXXZ"(
+// CHECK: %[[ref_tmp:.*]] = alloca i8*, align 4
+// CHECK: store i8* bitcast (void (%struct.A*)* @"?Foo@A@@QAEXXZ" to i8*), i8** %[[ref_tmp]], align 4
+// CHECK: call void @"?Bar@@YAXABQ8A@@AEXXZ@Z"(i8** dereferenceable(4) %[[ref_tmp]])
diff --git a/src/llvm-project/clang/test/CodeGenCXX/pr29160.cpp b/src/llvm-project/clang/test/CodeGenCXX/pr29160.cpp
new file mode 100644
index 0000000..09cf2a6
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/pr29160.cpp
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -std=c++11 -triple i686-linux-gnu %s -o /dev/null -S -emit-llvm
+//
+// This test's failure mode is running ~forever. (For some value of "forever"
+// that's greater than 25 minutes on my machine)
+
+template <typename... Ts>
+struct Foo {
+ template <typename... T>
+ static void ignore() {}
+ Foo() { ignore<Ts...>(); }
+};
+
+struct Base {
+ Base();
+ ~Base();
+};
+
+#define STAMP(thiz, prev) using thiz = Foo< \
+ prev, prev, prev, prev, prev, prev, prev, prev, prev, prev, prev, prev, \
+ prev, prev, prev, prev, prev, prev, prev, prev, prev, prev, prev, prev, \
+ prev, prev, prev, prev, prev, prev, prev, prev, prev, prev, prev, prev \
+ >;
+STAMP(A, Base);
+STAMP(B, A);
+STAMP(C, B);
+STAMP(D, C);
+STAMP(E, D);
+STAMP(F, E);
+STAMP(G, F);
+STAMP(H, G);
+STAMP(I, H);
+STAMP(J, I);
+STAMP(K, J);
+STAMP(L, K);
+STAMP(M, L);
+STAMP(N, M);
+STAMP(O, N);
+STAMP(P, O);
+STAMP(Q, P);
+
+int main() { Q q; }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/pr30731.cpp b/src/llvm-project/clang/test/CodeGenCXX/pr30731.cpp
new file mode 100644
index 0000000..36da43f
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/pr30731.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -triple i386-pc-win32 -emit-llvm -flto -std=c++11 -o - %s | FileCheck %s
+
+struct A {
+ virtual ~A();
+};
+
+struct B {};
+
+struct C {
+ virtual void f();
+};
+
+struct S : A, virtual B, C {
+ void f() override;
+};
+
+void f(S* s) { s->f(); }
+
+// CHECK-LABEL: define dso_local void @"?f@@YAXPAUS@@@Z"
+// CHECK: call
+// CHECK: ret void
diff --git a/src/llvm-project/clang/test/CodeGenCXX/pr31054.cpp b/src/llvm-project/clang/test/CodeGenCXX/pr31054.cpp
new file mode 100644
index 0000000..33b17b9
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/pr31054.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s
+
+struct A { ~A(); };
+void func() {
+ return;
+ static A k;
+}
+
+// Test that we did not crash, by checking whether function was created.
+// CHECK-LABEL: define void @_Z4funcv() #0 {
+// CHECK: ret void
+// CHECK: }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/pr33080.cpp b/src/llvm-project/clang/test/CodeGenCXX/pr33080.cpp
new file mode 100644
index 0000000..bae47cc
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/pr33080.cpp
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -fms-extensions -emit-llvm -o- %s | FileCheck %s
+
+void fa(__unaligned struct A *) {}
+// CHECK: define {{(dso_local )?}}void @_Z2faPU11__unaligned1A(
+
+void ga(struct A *, struct A *) {}
+// CHECK: define {{(dso_local )?}}void @_Z2gaP1AS0_(
+
+void gb(__unaligned struct A *, struct A *) {}
+// CHECK: define {{(dso_local )?}}void @_Z2gbPU11__unaligned1APS_(
+
+void gc(struct A *, __unaligned struct A *) {}
+// CHECK: define {{(dso_local )?}}void @_Z2gcP1APU11__unalignedS_(
+
+void gd(__unaligned struct A *, __unaligned struct A *) {}
+// CHECK: define {{(dso_local )?}}void @_Z2gdPU11__unaligned1AS1_(
+
+void hb(__unaligned struct A *, __unaligned const struct A *) {}
+// CHECK: define {{(dso_local )?}}void @_Z2hbPU11__unaligned1APU11__unalignedKS_(
+
+void ja(__unaligned struct A *, __unaligned struct A *__unaligned *, __unaligned struct A *__unaligned *__unaligned *) {}
+// CHECK: define {{(dso_local )?}}void @_Z2jaPU11__unaligned1APU11__unalignedS1_PU11__unalignedS3_(
+
+struct A;
+void memptr(void (A::*a)(int) __unaligned) {}
+// CHECK: define {{.*}} @_Z6memptrM1AU11__unalignedFviE(
+
+void jb(__unaligned struct A *, __unaligned struct A **, __unaligned struct A *__unaligned *__unaligned *) {}
+// CHECK: @_Z2jbPU11__unaligned1APS1_PU11__unalignedPU11__unalignedS1_(
+
+template <typename T, typename Q>
+void ta(T &, Q *) {}
+
+void ia(__unaligned struct A &a) {
+ ta(a, &a);
+}
+// CHECK: @_Z2taIU11__unaligned1AS1_EvRT_PT0_(
diff --git a/src/llvm-project/clang/test/CodeGenCXX/pr34163.cpp b/src/llvm-project/clang/test/CodeGenCXX/pr34163.cpp
new file mode 100644
index 0000000..a200a0f
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/pr34163.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=standalone -triple x86_64-linux-gnu -o - -x c++ %s | FileCheck %s
+
+void f(struct X *) {}
+
+// CHECK: @_ZTV1X =
+struct X {
+ void a() { delete this; }
+ virtual ~X() {}
+ virtual void key_function();
+};
+
+// CHECK: define {{.*}} @_ZN1X12key_functionEv(
+void X::key_function() {}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/pr9130.cpp b/src/llvm-project/clang/test/CodeGenCXX/pr9130.cpp
new file mode 100644
index 0000000..e726e5a
--- /dev/null
+++ b/src/llvm-project/clang/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-LABEL: define linkonce_odr i32 @_ZN15nsOggCodecState9StartTimeEv
diff --git a/src/llvm-project/clang/test/CodeGenCXX/pr9965.cpp b/src/llvm-project/clang/test/CodeGenCXX/pr9965.cpp
new file mode 100644
index 0000000..95ba2be
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/pr9965.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
+struct A { A(); };
+template<typename T>
+struct X : A // default constructor is not trivial
+{
+ X() = default;
+ ~X() {} // not a literal type
+};
+
+X<int> x;
+// CHECK-LABEL: define internal {{.*}}void @__cxx_global_var_init()
+// CHECK: call {{.*}} @_ZN1XIiEC1Ev
+// CHECK: define linkonce_odr {{.*}} @_ZN1XIiEC1Ev
+// CHECK: define linkonce_odr {{.*}} @_ZN1XIiEC2Ev
diff --git a/src/llvm-project/clang/test/CodeGenCXX/pragma-init_seg.cpp b/src/llvm-project/clang/test/CodeGenCXX/pragma-init_seg.cpp
new file mode 100644
index 0000000..f0b1559
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/pragma-init_seg.cpp
@@ -0,0 +1,72 @@
+// RUN: %clang_cc1 %s -triple=i686-pc-win32 -fms-extensions -emit-llvm -o - | FileCheck %s
+
+int f();
+
+// CHECK: $"?x@selectany_init@@3HA" = comdat any
+// CHECK: $"?x@?$A@H@explicit_template_instantiation@@2HB" = comdat any
+// CHECK: $"?x@?$A@H@implicit_template_instantiation@@2HB" = comdat any
+
+namespace simple_init {
+#pragma init_seg(compiler)
+int x = f();
+// CHECK: @"?x@simple_init@@3HA" = dso_local global i32 0, align 4
+// CHECK: @__cxx_init_fn_ptr = private constant void ()* @"??__Ex@simple_init@@YAXXZ", section ".CRT$XCC"
+
+#pragma init_seg(lib)
+int y = f();
+// CHECK: @"?y@simple_init@@3HA" = dso_local global i32 0, align 4
+// CHECK: @__cxx_init_fn_ptr.1 = private constant void ()* @"??__Ey@simple_init@@YAXXZ", section ".CRT$XCL"
+
+#pragma init_seg(user)
+int z = f();
+// CHECK: @"?z@simple_init@@3HA" = dso_local global i32 0, align 4
+// No function pointer! This one goes on @llvm.global_ctors.
+}
+
+#pragma init_seg(".asdf")
+
+namespace internal_init {
+namespace {
+int x = f();
+// CHECK: @"?x@?A0x{{[^@]*}}@internal_init@@3HA" = internal global i32 0, align 4
+// CHECK: @__cxx_init_fn_ptr.2 = private constant void ()* @"??__Ex@?A0x{{[^@]*}}@internal_init@@YAXXZ", section ".asdf"
+}
+}
+
+namespace selectany_init {
+int __declspec(selectany) x = f();
+// CHECK: @"?x@selectany_init@@3HA" = weak_odr dso_local global i32 0, comdat, align 4
+// CHECK: @__cxx_init_fn_ptr.3 = private constant void ()* @"??__Ex@selectany_init@@YAXXZ", section ".asdf", comdat($"?x@selectany_init@@3HA")
+}
+
+namespace explicit_template_instantiation {
+template <typename T> struct A { static const int x; };
+template <typename T> const int A<T>::x = f();
+template struct A<int>;
+// CHECK: @"?x@?$A@H@explicit_template_instantiation@@2HB" = weak_odr dso_local global i32 0, comdat, align 4
+// CHECK: @__cxx_init_fn_ptr.4 = private constant void ()* @"??__E?x@?$A@H@explicit_template_instantiation@@2HB@@YAXXZ", section ".asdf", comdat($"?x@?$A@H@explicit_template_instantiation@@2HB")
+}
+
+namespace implicit_template_instantiation {
+template <typename T> struct A { static const int x; };
+template <typename T> const int A<T>::x = f();
+int g() { return A<int>::x; }
+// CHECK: @"?x@?$A@H@implicit_template_instantiation@@2HB" = linkonce_odr dso_local global i32 0, comdat, align 4
+// CHECK: @__cxx_init_fn_ptr.5 = private constant void ()* @"??__E?x@?$A@H@implicit_template_instantiation@@2HB@@YAXXZ", section ".asdf", comdat($"?x@?$A@H@implicit_template_instantiation@@2HB")
+}
+
+// ... and here's where we emitted user level ctors.
+// CHECK: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }]
+// CHECK: [{ i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_pragma_init_seg.cpp, i8* null }]
+
+// We have to mark everything used so we can survive globalopt, even through
+// LTO. There's no way LLVM could really understand if data in the .asdf
+// section is really used or dead.
+//
+// CHECK: @llvm.used = appending global [6 x i8*]
+// CHECK: [i8* bitcast (void ()** @__cxx_init_fn_ptr to i8*),
+// CHECK: i8* bitcast (void ()** @__cxx_init_fn_ptr.1 to i8*),
+// CHECK: i8* bitcast (void ()** @__cxx_init_fn_ptr.2 to i8*),
+// CHECK: i8* bitcast (void ()** @__cxx_init_fn_ptr.3 to i8*),
+// CHECK: i8* bitcast (void ()** @__cxx_init_fn_ptr.4 to i8*),
+// CHECK: i8* bitcast (void ()** @__cxx_init_fn_ptr.5 to i8*)], section "llvm.metadata"
diff --git a/src/llvm-project/clang/test/CodeGenCXX/pragma-loop-distribute.cpp b/src/llvm-project/clang/test/CodeGenCXX/pragma-loop-distribute.cpp
new file mode 100644
index 0000000..a692559
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/pragma-loop-distribute.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm -o - %s | FileCheck %s
+
+void while_test(int *List, int Length, int *List2, int Length2) {
+ // CHECK: define {{.*}} @_Z10while_test
+ int i = 0;
+
+#pragma clang loop distribute(enable)
+ while (i < Length) {
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_1:.*]]
+ List[i] = i * 2;
+ i++;
+ }
+
+ i = 0;
+ while (i < Length2) {
+ // CHECK-NOT: br label {{.*}}, !llvm.loop
+ List2[i] = i * 2;
+ i++;
+ }
+}
+
+// CHECK: ![[LOOP_1]] = distinct !{![[LOOP_1]], ![[DISTRIBUTE_ENABLE:.*]]}
+// CHECK: ![[DISTRIBUTE_ENABLE]] = !{!"llvm.loop.distribute.enable", i1 true}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/pragma-loop-safety-imperfectly_nested.cpp b/src/llvm-project/clang/test/CodeGenCXX/pragma-loop-safety-imperfectly_nested.cpp
new file mode 100644
index 0000000..da060f7
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/pragma-loop-safety-imperfectly_nested.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm -o - %s | FileCheck %s
+
+// Verify that the outer loop has the llvm.access.group property for the
+// accesses outside and inside the inner loop, even when the inner loop
+// is not perfectly nested.
+void vectorize_imperfectly_nested_test(int *List, int Length) {
+#pragma clang loop vectorize(assume_safety) interleave(disable) unroll(disable)
+ for (int i = 0; i < Length; ++i) {
+ List[i * Length] = 42;
+#pragma clang loop vectorize(assume_safety) interleave(disable) unroll(disable)
+ for (int j = 1; j < Length - 1; ++j)
+ List[i * Length + j] = (i + j) * 2;
+ List[(i + 1) * Length - 1] = 21;
+ }
+}
+
+
+// CHECK: load i32, i32* %Length.addr, align 4, !llvm.access.group ![[ACCESS_GROUP_2:[0-9]+]]
+
+// CHECK: %[[MUL:.+]] = mul nsw i32 %add, 2
+// CHECK: store i32 %[[MUL]], i32* %{{.+}}, !llvm.access.group ![[ACCESS_GROUP_3:[0-9]+]]
+// CHECK: br label %{{.+}}, !llvm.loop ![[INNER_LOOPID:[0-9]+]]
+// CHECK: store i32 21, i32* %{{.+}}, !llvm.access.group ![[ACCESS_GROUP_2]]
+// CHECK: br label %{{.+}}, !llvm.loop ![[OUTER_LOOPID:[0-9]+]]
+
+// CHECK: ![[ACCESS_GROUP_2]] = distinct !{}
+// CHECK: ![[ACCESS_GROUP_LIST_3:[0-9]+]] = !{![[ACCESS_GROUP_2]], ![[ACCESS_GROUP_4:[0-9]+]]}
+// CHECK: ![[ACCESS_GROUP_4]] = distinct !{}
+// CHECK: ![[INNER_LOOPID]] = distinct !{![[INNER_LOOPID]], {{.*}} ![[PARALLEL_ACCESSES_8:[0-9]+]]}
+// CHECK: ![[PARALLEL_ACCESSES_8]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_4]]}
+// CHECK: ![[OUTER_LOOPID]] = distinct !{![[OUTER_LOOPID]], {{.*}} ![[PARALLEL_ACCESSES_10:[0-9]+]]}
+// CHECK: ![[PARALLEL_ACCESSES_10]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_2]]}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/pragma-loop-safety-nested.cpp b/src/llvm-project/clang/test/CodeGenCXX/pragma-loop-safety-nested.cpp
new file mode 100644
index 0000000..deec06b
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/pragma-loop-safety-nested.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm -o - %s | FileCheck %s
+
+// Verify that the outer loop has the llvm.access.group property for the
+// accesses outside and inside the inner loop.
+void vectorize_nested_test(int *List, int Length) {
+#pragma clang loop vectorize(assume_safety) interleave(disable) unroll(disable)
+ for (int i = 0; i < Length; ++i) {
+#pragma clang loop vectorize(assume_safety) interleave(disable) unroll(disable)
+ for (int j = 0; j < Length; ++j)
+ List[i * Length + j] = (i + j) * 2;
+ }
+}
+
+
+// CHECK: load i32, i32* %Length.addr, align 4, !llvm.access.group ![[ACCESS_GROUP_2:[0-9]+]]
+// CHECK: %[[MUL:.+]] = mul
+// CHECK: store i32 %[[MUL]], i32* %{{.+}}, !llvm.access.group ![[ACCESS_GROUP_LIST_3:[0-9]+]]
+// CHECK: br label %{{.+}}, !llvm.loop ![[INNER_LOOPID:[0-9]+]]
+// CHECK: br label %{{.+}}, !llvm.loop ![[OUTER_LOOPID:[0-9]+]]
+
+// CHECK: ![[ACCESS_GROUP_2]] = distinct !{}
+// CHECK: ![[ACCESS_GROUP_LIST_3]] = !{![[ACCESS_GROUP_2]], ![[ACCESS_GROUP_4:[0-9]+]]}
+// CHECK: ![[ACCESS_GROUP_4]] = distinct !{}
+// CHECK: ![[INNER_LOOPID]] = distinct !{![[INNER_LOOPID]], {{.*}} ![[PARALLEL_ACCESSES_8:[0-9]+]]}
+// CHECK: ![[PARALLEL_ACCESSES_8]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_4]]}
+// CHECK: ![[OUTER_LOOPID]] = distinct !{![[OUTER_LOOPID]], {{.*}} ![[PARALLEL_ACCESSES_10:[0-9]+]]}
+// CHECK: ![[PARALLEL_ACCESSES_10]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_2]]}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/pragma-loop-safety-outer.cpp b/src/llvm-project/clang/test/CodeGenCXX/pragma-loop-safety-outer.cpp
new file mode 100644
index 0000000..d99b86f
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/pragma-loop-safety-outer.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm -o - %s | FileCheck %s
+
+// Verify that the outer loop has the inner loop's access in its
+// llvm.loop.parallel_accesses property.
+void vectorize_outer_test(int *List, int Length) {
+#pragma clang loop vectorize(assume_safety) interleave(disable) unroll(disable)
+ for (int i = 0; i < Length; i += 2) {
+#pragma clang loop unroll(full)
+ for (int j = 0; j < 2; j += 1)
+ List[i + j] = (i + j) * 2;
+ }
+}
+
+// CHECK: %[[MUL:.+]] = mul
+// CHECK: store i32 %[[MUL]], i32* %{{.+}}, !llvm.access.group ![[ACCESS_GROUP_2:[0-9]+]]
+// CHECK: br label %{{.+}}, !llvm.loop ![[INNER_LOOPID:[0-9]+]]
+// CHECK: br label %{{.+}}, !llvm.loop ![[OUTER_LOOPID:[0-9]+]]
+
+// CHECK: ![[ACCESS_GROUP_2]] = distinct !{}
+// CHECK: ![[INNER_LOOPID]] = distinct !{![[INNER_LOOPID]],
+// CHECK: ![[OUTER_LOOPID]] = distinct !{![[OUTER_LOOPID]], {{.*}} ![[PARALLEL_ACCESSES_9:[0-9]+]]}
+// CHECK: ![[PARALLEL_ACCESSES_9]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_2]]}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/pragma-loop-safety.cpp b/src/llvm-project/clang/test/CodeGenCXX/pragma-loop-safety.cpp
new file mode 100644
index 0000000..c0b10b0
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/pragma-loop-safety.cpp
@@ -0,0 +1,58 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm -o - %s | FileCheck %s
+
+// Verify assume_safety vectorization is recognized.
+void vectorize_test(int *List, int Length) {
+// CHECK: define {{.*}} @_Z14vectorize_test
+// CHECK: [[LOAD1_IV:.+]] = load i32, i32* [[IV1:[^,]+]], {{.*}}!llvm.access.group ![[ACCESS_GROUP_2:[0-9]+]]
+// CHECK-NEXT: [[LOAD1_LEN:.+]] = load i32, i32* [[LEN1:.+]], {{.*}}!llvm.access.group ![[ACCESS_GROUP_2]]
+// CHECK-NEXT: [[CMP1:.+]] = icmp slt i32[[LOAD1_IV]],[[LOAD1_LEN]]
+// CHECK-NEXT: br i1[[CMP1]], label %[[LOOP1_BODY:[^,]+]], label %[[LOOP1_END:[^,]+]]
+#pragma clang loop vectorize(assume_safety) interleave(disable) unroll(disable)
+ for (int i = 0; i < Length; i++) {
+ // CHECK: [[RHIV1:.+]] = load i32, i32* [[IV1]], {{.*}}!llvm.access.group ![[ACCESS_GROUP_2]]
+ // CHECK-DAG: [[CALC1:.+]] = mul nsw i32[[RHIV1]], 2
+ // CHECK-DAG: [[SIV1:.+]] = load i32, i32* [[IV1]]{{.*}}!llvm.access.group ![[ACCESS_GROUP_2]]
+ // CHECK-DAG: [[INDEX1:.+]] = sext i32[[SIV1]] to i64
+ // CHECK-DAG: [[ARRAY1:.+]] = load i32*, i32** [[LIST1:.*]], {{.*}}!llvm.access.group ![[ACCESS_GROUP_2]]
+ // CHECK-DAG: [[PTR1:.+]] = getelementptr inbounds i32, i32*[[ARRAY1]], i64[[INDEX1]]
+ // CHECK: store i32[[CALC1]], i32*[[PTR1]], {{.*}}!llvm.access.group ![[ACCESS_GROUP_2]]
+ // CHECK-NEXT: br label [[LOOP1_INC:[^,]+]]
+ List[i] = i * 2;
+
+ // CHECK: br label [[LOOP1_COND:[^,]+]], !llvm.loop ![[LOOP1_HINTS:[0-9]+]]
+ }
+}
+
+// Verify assume_safety interleaving is recognized.
+void interleave_test(int *List, int Length) {
+// CHECK: define {{.*}} @_Z15interleave_test
+// CHECK: [[LOAD2_IV:.+]] = load i32, i32* [[IV2:[^,]+]], {{.*}}!llvm.access.group ![[ACCESS_GROUP_8:[0-9]+]]
+// CHECK-NEXT: [[LOAD2_LEN:.+]] = load i32, i32* [[LEN2:.+]], {{.*}}!llvm.access.group ![[ACCESS_GROUP_8]]
+// CHECK-NEXT: [[CMP2:.+]] = icmp slt i32[[LOAD2_IV]],[[LOAD2_LEN]]
+// CHECK-NEXT: br i1[[CMP2]], label %[[LOOP2_BODY:[^,]+]], label %[[LOOP2_END:[^,]+]]
+#pragma clang loop interleave(assume_safety) vectorize(disable) unroll(disable)
+ for (int i = 0; i < Length; i++) {
+ // CHECK: [[RHIV2:.+]] = load i32, i32* [[IV2]], {{.*}}!llvm.access.group ![[ACCESS_GROUP_8]]
+ // CHECK-DAG: [[CALC2:.+]] = mul nsw i32[[RHIV2]], 2
+ // CHECK-DAG: [[SIV2:.+]] = load i32, i32* [[IV2]]{{.*}}!llvm.access.group ![[ACCESS_GROUP_8]]
+ // CHECK-DAG: [[INDEX2:.+]] = sext i32[[SIV2]] to i64
+ // CHECK-DAG: [[ARRAY2:.+]] = load i32*, i32** [[LIST2:.*]], {{.*}}!llvm.access.group ![[ACCESS_GROUP_8]]
+ // CHECK-DAG: [[PTR2:.+]] = getelementptr inbounds i32, i32*[[ARRAY2]], i64[[INDEX2]]
+ // CHECK: store i32[[CALC2]], i32*[[PTR2]], {{.*}}!llvm.access.group ![[ACCESS_GROUP_8]]
+ // CHECK-NEXT: br label [[LOOP2_INC:[^,]+]]
+ List[i] = i * 2;
+
+ // CHECK: br label [[LOOP2_COND:[^,]+]], !llvm.loop ![[LOOP2_HINTS:[0-9]+]]
+ }
+}
+
+// CHECK: ![[ACCESS_GROUP_2]] = distinct !{}
+// CHECK: ![[LOOP1_HINTS]] = distinct !{![[LOOP1_HINTS]], ![[INTERLEAVE_1:[0-9]+]], ![[INTENABLE_1:[0-9]+]], ![[UNROLL_DISABLE:[0-9]+]], ![[PARALLEL_ACCESSES_7:[0-9]+]]}
+// CHECK: ![[INTERLEAVE_1]] = !{!"llvm.loop.interleave.count", i32 1}
+// CHCCK: ![[INTENABLE_1]] = !{!"llvm.loop.vectorize.enable", i1 true}
+// CHECK: ![[UNROLL_DISABLE]] = !{!"llvm.loop.unroll.disable"}
+// CHECK: ![[PARALLEL_ACCESSES_7]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_2]]}
+// CHECK: ![[ACCESS_GROUP_8]] = distinct !{}
+// CHECK: ![[LOOP2_HINTS]] = distinct !{![[LOOP2_HINTS]], ![[WIDTH_1:[0-9]+]], ![[INTENABLE_1]], ![[UNROLL_DISABLE]], ![[PARALLEL_ACCESSES_11:[0-9]+]]}
+// CHECK: ![[WIDTH_1]] = !{!"llvm.loop.vectorize.width", i32 1}
+// CHECK: ![[PARALLEL_ACCESSES_11]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_8]]}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/pragma-loop.cpp b/src/llvm-project/clang/test/CodeGenCXX/pragma-loop.cpp
new file mode 100644
index 0000000..e337913
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/pragma-loop.cpp
@@ -0,0 +1,194 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm -o - %s | FileCheck %s
+
+// Verify while loop is recognized after sequence of pragma clang loop directives.
+void while_test(int *List, int Length) {
+ // CHECK: define {{.*}} @_Z10while_test
+ int i = 0;
+
+#pragma clang loop vectorize(enable)
+#pragma clang loop interleave_count(4)
+#pragma clang loop vectorize_width(4)
+#pragma clang loop unroll(full)
+#pragma clang loop distribute(enable)
+ while (i < Length) {
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_1:.*]]
+ List[i] = i * 2;
+ i++;
+ }
+}
+
+// Verify do loop is recognized after multi-option pragma clang loop directive.
+void do_test(int *List, int Length) {
+ int i = 0;
+
+#pragma clang loop vectorize_width(8) interleave_count(4) unroll(disable) distribute(disable)
+ do {
+ // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_2:.*]]
+ List[i] = i * 2;
+ i++;
+ } while (i < Length);
+}
+
+enum struct Tuner : short { Interleave = 4, Unroll = 8 };
+
+// Verify for loop is recognized after sequence of pragma clang loop directives.
+void for_test(int *List, int Length) {
+#pragma clang loop interleave(enable)
+#pragma clang loop interleave_count(static_cast<int>(Tuner::Interleave))
+#pragma clang loop unroll_count(static_cast<int>(Tuner::Unroll))
+ for (int i = 0; i < Length; i++) {
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_3:.*]]
+ List[i] = i * 2;
+ }
+}
+
+// Verify c++11 for range loop is recognized after
+// sequence of pragma clang loop directives.
+void for_range_test() {
+ double List[100];
+
+#pragma clang loop vectorize_width(2) interleave_count(2)
+ for (int i : List) {
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_4:.*]]
+ List[i] = i;
+ }
+}
+
+// Verify disable pragma clang loop directive generates correct metadata
+void disable_test(int *List, int Length) {
+#pragma clang loop vectorize(disable) unroll(disable) distribute(disable)
+ for (int i = 0; i < Length; i++) {
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_5:.*]]
+ List[i] = i * 2;
+ }
+}
+
+#define VECWIDTH 2
+#define INTCOUNT 2
+#define UNROLLCOUNT 8
+
+// Verify defines are correctly resolved in pragma clang loop directive
+void for_define_test(int *List, int Length, int Value) {
+#pragma clang loop vectorize_width(VECWIDTH) interleave_count(INTCOUNT)
+#pragma clang loop unroll_count(UNROLLCOUNT)
+ for (int i = 0; i < Length; i++) {
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_6:.*]]
+ List[i] = i * Value;
+ }
+}
+
+// Verify constant expressions are handled correctly.
+void for_contant_expression_test(int *List, int Length) {
+#pragma clang loop vectorize_width(1 + 4)
+ for (int i = 0; i < Length; i++) {
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_7:.*]]
+ List[i] = i;
+ }
+
+#pragma clang loop vectorize_width(3 + VECWIDTH)
+ for (int i = 0; i < Length; i++) {
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_8:.*]]
+ List[i] += i;
+ }
+}
+
+// Verify metadata is generated when template is used.
+template <typename A>
+void for_template_test(A *List, int Length, A Value) {
+#pragma clang loop vectorize_width(8) interleave_count(8) unroll_count(8)
+ for (int i = 0; i < Length; i++) {
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_9:.*]]
+ List[i] = i * Value;
+ }
+}
+
+// Verify define is resolved correctly when template is used.
+template <typename A, typename T>
+void for_template_define_test(A *List, int Length, A Value) {
+ const T VWidth = VECWIDTH;
+ const T ICount = INTCOUNT;
+ const T UCount = UNROLLCOUNT;
+#pragma clang loop vectorize_width(VWidth) interleave_count(ICount)
+#pragma clang loop unroll_count(UCount)
+ for (int i = 0; i < Length; i++) {
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_10:.*]]
+ List[i] = i * Value;
+ }
+}
+
+// Verify templates and constant expressions are handled correctly.
+template <typename A, int V, int I, int U>
+void for_template_constant_expression_test(A *List, int Length) {
+#pragma clang loop vectorize_width(V) interleave_count(I) unroll_count(U)
+ for (int i = 0; i < Length; i++) {
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_11:.*]]
+ List[i] = i;
+ }
+
+#pragma clang loop vectorize_width(V * 2 + VECWIDTH) interleave_count(I * 2 + INTCOUNT) unroll_count(U * 2 + UNROLLCOUNT)
+ for (int i = 0; i < Length; i++) {
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_12:.*]]
+ List[i] += i;
+ }
+
+ const int Scale = 4;
+#pragma clang loop vectorize_width(Scale * V) interleave_count(Scale * I) unroll_count(Scale * U)
+ for (int i = 0; i < Length; i++) {
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_13:.*]]
+ List[i] += i;
+ }
+
+#pragma clang loop vectorize_width((Scale * V) + 2)
+ for (int i = 0; i < Length; i++) {
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_14:.*]]
+ List[i] += i;
+ }
+}
+
+#undef VECWIDTH
+#undef INTCOUNT
+#undef UNROLLCOUNT
+
+// Use templates defined above. Test verifies metadata is generated correctly.
+void template_test(double *List, int Length) {
+ double Value = 10;
+
+ for_template_test<double>(List, Length, Value);
+ for_template_define_test<double, int>(List, Length, Value);
+ for_template_constant_expression_test<double, 2, 4, 8>(List, Length);
+}
+
+// CHECK: ![[LOOP_1]] = distinct !{![[LOOP_1]], ![[WIDTH_4:.*]], ![[INTERLEAVE_4:.*]], ![[INTENABLE_1:.*]], ![[UNROLL_FULL:.*]], ![[DISTRIBUTE_ENABLE:.*]]}
+// CHECK: ![[WIDTH_4]] = !{!"llvm.loop.vectorize.width", i32 4}
+// CHECK: ![[INTERLEAVE_4]] = !{!"llvm.loop.interleave.count", i32 4}
+// CHECK: ![[INTENABLE_1]] = !{!"llvm.loop.vectorize.enable", i1 true}
+// CHECK: ![[UNROLL_FULL]] = !{!"llvm.loop.unroll.full"}
+// CHECK: ![[DISTRIBUTE_ENABLE]] = !{!"llvm.loop.distribute.enable", i1 true}
+// CHECK: ![[LOOP_2]] = distinct !{![[LOOP_2:.*]], ![[WIDTH_8:.*]], ![[INTERLEAVE_4:.*]], ![[UNROLL_DISABLE:.*]], ![[DISTRIBUTE_DISABLE:.*]]}
+// CHECK: ![[WIDTH_8]] = !{!"llvm.loop.vectorize.width", i32 8}
+// CHECK: ![[UNROLL_DISABLE]] = !{!"llvm.loop.unroll.disable"}
+// CHECK: ![[DISTRIBUTE_DISABLE]] = !{!"llvm.loop.distribute.enable", i1 false}
+// CHECK: ![[LOOP_3]] = distinct !{![[LOOP_3]], ![[INTERLEAVE_4:.*]], ![[UNROLL_8:.*]], ![[INTENABLE_1:.*]]}
+// CHECK: ![[UNROLL_8]] = !{!"llvm.loop.unroll.count", i32 8}
+// CHECK: ![[LOOP_4]] = distinct !{![[LOOP_4]], ![[WIDTH_2:.*]], ![[INTERLEAVE_2:.*]]}
+// CHECK: ![[WIDTH_2]] = !{!"llvm.loop.vectorize.width", i32 2}
+// CHECK: ![[INTERLEAVE_2]] = !{!"llvm.loop.interleave.count", i32 2}
+// CHECK: ![[LOOP_5]] = distinct !{![[LOOP_5]], ![[WIDTH_1:.*]], ![[UNROLL_DISABLE:.*]], ![[DISTRIBUTE_DISABLE:.*]]}
+// CHECK: ![[WIDTH_1]] = !{!"llvm.loop.vectorize.width", i32 1}
+// CHECK: ![[LOOP_6]] = distinct !{![[LOOP_6]], ![[WIDTH_2:.*]], ![[INTERLEAVE_2:.*]], ![[UNROLL_8:.*]]}
+// CHECK: ![[LOOP_7]] = distinct !{![[LOOP_7]], ![[WIDTH_5:.*]]}
+// CHECK: ![[WIDTH_5]] = !{!"llvm.loop.vectorize.width", i32 5}
+// CHECK: ![[LOOP_8]] = distinct !{![[LOOP_8]], ![[WIDTH_5:.*]]}
+// CHECK: ![[LOOP_9]] = distinct !{![[LOOP_9]], ![[WIDTH_8:.*]], ![[INTERLEAVE_8:.*]], ![[UNROLL_8:.*]]}
+// CHECK: ![[INTERLEAVE_8]] = !{!"llvm.loop.interleave.count", i32 8}
+// CHECK: ![[LOOP_10]] = distinct !{![[LOOP_10]], ![[WIDTH_2:.*]], ![[INTERLEAVE_2:.*]], ![[UNROLL_8:.*]]}
+// CHECK: ![[LOOP_11]] = distinct !{![[LOOP_11]], ![[WIDTH_2:.*]], ![[INTERLEAVE_4:.*]], ![[UNROLL_8:.*]]}
+// CHECK: ![[LOOP_12]] = distinct !{![[LOOP_12]], ![[WIDTH_6:.*]], ![[INTERLEAVE_10:.*]], ![[UNROLL_24:.*]]}
+// CHECK: ![[WIDTH_6]] = !{!"llvm.loop.vectorize.width", i32 6}
+// CHECK: ![[INTERLEAVE_10]] = !{!"llvm.loop.interleave.count", i32 10}
+// CHECK: ![[UNROLL_24]] = !{!"llvm.loop.unroll.count", i32 24}
+// CHECK: ![[LOOP_13]] = distinct !{![[LOOP_13]], ![[WIDTH_8:.*]], ![[INTERLEAVE_16:.*]], ![[UNROLL_32:.*]]}
+// CHECK: ![[INTERLEAVE_16]] = !{!"llvm.loop.interleave.count", i32 16}
+// CHECK: ![[UNROLL_32]] = !{!"llvm.loop.unroll.count", i32 32}
+// CHECK: ![[LOOP_14]] = distinct !{![[LOOP_14]], ![[WIDTH_10:.*]]}
+// CHECK: ![[WIDTH_10]] = !{!"llvm.loop.vectorize.width", i32 10}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/pragma-pack-2.cpp b/src/llvm-project/clang/test/CodeGenCXX/pragma-pack-2.cpp
new file mode 100644
index 0000000..9c09d5b
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/pragma-pack-2.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.7.2 %s -emit-llvm -o - | FileCheck %s
+// <rdar://problem/10551376>
+
+struct FOO {
+ unsigned int x;
+};
+
+#pragma pack(push, 2)
+
+// CHECK: %struct.BAR = type <{ %struct.FOO, i8, i8 }>
+struct BAR : FOO {
+ char y;
+};
+
+#pragma pack(pop)
+
+BAR* x = 0;
\ No newline at end of file
diff --git a/src/llvm-project/clang/test/CodeGenCXX/pragma-pack-3.cpp b/src/llvm-project/clang/test/CodeGenCXX/pragma-pack-3.cpp
new file mode 100644
index 0000000..49509a5b
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/pragma-pack-3.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 %s -triple=i686-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+struct Base {
+ char a;
+};
+
+struct Derived_1 : virtual Base
+{
+ char b;
+};
+
+#pragma pack(1)
+struct Derived_2 : Derived_1 {
+ // CHECK: %struct.Derived_2 = type { %struct.Derived_1.base, %struct.Base }
+ // CHECK: %struct.Derived_1.base = type <{ i32 (...)**, i8 }>
+};
+
+Derived_2 x;
diff --git a/src/llvm-project/clang/test/CodeGenCXX/pragma-pack.cpp b/src/llvm-project/clang/test/CodeGenCXX/pragma-pack.cpp
new file mode 100644
index 0000000..c0b0259
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/pragma-pack.cpp
@@ -0,0 +1,16 @@
+// 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, %struct.Base }>
+void f(Sub*) { }
+
+static int i[sizeof(Sub) == 13 ? 1 : -1];
diff --git a/src/llvm-project/clang/test/CodeGenCXX/pragma-pipeline.cpp b/src/llvm-project/clang/test/CodeGenCXX/pragma-pipeline.cpp
new file mode 100644
index 0000000..6846f15
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/pragma-pipeline.cpp
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -triple hexagon -std=c++11 -emit-llvm -o - %s | FileCheck %s
+
+void pipeline_disabled(int *List, int Length, int Value) {
+// CHECK-LABEL: define {{.*}} @_Z17pipeline_disabled
+#pragma clang loop pipeline(disable)
+ for (int i = 0; i < Length; i++) {
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_1:.*]]
+ List[i] = Value;
+ }
+}
+
+void pipeline_not_disabled(int *List, int Length, int Value) {
+ // CHECK-LABEL: define {{.*}} @_Z21pipeline_not_disabled
+ for (int i = 0; i < Length; i++) {
+ List[i] = Value;
+ }
+}
+
+void pipeline_initiation_interval(int *List, int Length, int Value) {
+// CHECK-LABEL: define {{.*}} @_Z28pipeline_initiation_interval
+#pragma clang loop pipeline_initiation_interval(10)
+ for (int i = 0; i < Length; i++) {
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_3:.*]]
+ List[i] = Value;
+ }
+}
+
+void pipeline_disabled_on_nested_loop(int *List, int Length, int Value) {
+ // CHECK-LABEL: define {{.*}} @_Z32pipeline_disabled_on_nested_loop
+ for (int i = 0; i < Length; i++) {
+#pragma clang loop pipeline(disable)
+ for (int j = 0; j < Length; j++) {
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_4:.*]]
+ List[i * Length + j] = Value;
+ }
+ }
+}
+
+// CHECK: ![[LOOP_1]] = distinct !{![[LOOP_1]], ![[PIPELINE_DISABLE:.*]]}
+// CHECK: ![[PIPELINE_DISABLE]] = !{!"llvm.loop.pipeline.disable", i1 true}
+
+// CHECK-NOT:llvm.loop.pipeline
+
+// CHECK: ![[LOOP_3]] = distinct !{![[LOOP_3]], ![[PIPELINE_II_10:.*]]}
+// CHECK: ![[PIPELINE_II_10]] = !{!"llvm.loop.pipeline.initiationinterval", i32 10}
+
+// CHECK: ![[LOOP_4]] = distinct !{![[LOOP_4]], ![[PIPELINE_DISABLE]]}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/pragma-unroll-and-jam.cpp b/src/llvm-project/clang/test/CodeGenCXX/pragma-unroll-and-jam.cpp
new file mode 100644
index 0000000..9842126
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/pragma-unroll-and-jam.cpp
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -triple arm-none-eabi -std=c++11 -emit-llvm -o - %s | FileCheck %s
+
+void unroll_and_jam(int *List, int Length, int Value) {
+ // CHECK-LABEL: define {{.*}} @_Z14unroll_and_jam
+#pragma unroll_and_jam
+ for (int i = 0; i < Length; i++) {
+ for (int j = 0; j < Length; j++) {
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_1:.*]]
+ List[i * Length + j] = Value;
+ }
+ }
+}
+
+void unroll_and_jam_count(int *List, int Length, int Value) {
+ // CHECK-LABEL: define {{.*}} @_Z20unroll_and_jam_count
+#pragma unroll_and_jam(4)
+ for (int i = 0; i < Length; i++) {
+ for (int j = 0; j < Length; j++) {
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_2:.*]]
+ List[i * Length + j] = Value;
+ }
+ }
+}
+
+void nounroll_and_jam(int *List, int Length, int Value) {
+ // CHECK-LABEL: define {{.*}} @_Z16nounroll_and_jam
+#pragma nounroll_and_jam
+ for (int i = 0; i < Length; i++) {
+ for (int j = 0; j < Length; j++) {
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_3:.*]]
+ List[i * Length + j] = Value;
+ }
+ }
+}
+
+void clang_unroll_plus_nounroll_and_jam(int *List, int Length, int Value) {
+ // CHECK-LABEL: define {{.*}} @_Z34clang_unroll_plus_nounroll_and_jam
+#pragma nounroll_and_jam
+#pragma unroll(4)
+ for (int i = 0; i < Length; i++) {
+ for (int j = 0; j < Length; j++) {
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_7:.*]]
+ List[i * Length + j] = Value;
+ }
+ }
+}
+
+// CHECK: ![[LOOP_1]] = distinct !{![[LOOP_1]], ![[UNJ_ENABLE:.*]]}
+// CHECK: ![[UNJ_ENABLE]] = !{!"llvm.loop.unroll_and_jam.enable"}
+// CHECK: ![[LOOP_2]] = distinct !{![[LOOP_2]], ![[UNJ_4:.*]]}
+// CHECK: ![[UNJ_4]] = !{!"llvm.loop.unroll_and_jam.count", i32 4}
+// CHECK: ![[LOOP_3]] = distinct !{![[LOOP_3]], ![[UNJ_DISABLE:.*]]}
+// CHECK: ![[UNJ_DISABLE]] = !{!"llvm.loop.unroll_and_jam.disable"}
+// CHECK: ![[LOOP_7]] = distinct !{![[LOOP_7]], ![[UNROLL_4:.*]], ![[UNJ_DISABLE:.*]]}
+// CHECK: ![[UNROLL_4]] = !{!"llvm.loop.unroll.count", i32 4}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/pragma-unroll.cpp b/src/llvm-project/clang/test/CodeGenCXX/pragma-unroll.cpp
new file mode 100644
index 0000000..8f07909
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/pragma-unroll.cpp
@@ -0,0 +1,106 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm -o - %s | FileCheck %s
+
+// Verify while loop is recognized after unroll pragma.
+void while_test(int *List, int Length) {
+ // CHECK: define {{.*}} @_Z10while_test
+ int i = 0;
+
+#pragma unroll
+ while (i < Length) {
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_1:.*]]
+ List[i] = i * 2;
+ i++;
+ }
+}
+
+// Verify do loop is recognized after multi-option pragma clang loop directive.
+void do_test(int *List, int Length) {
+ // CHECK: define {{.*}} @_Z7do_test
+ int i = 0;
+
+#pragma nounroll
+ do {
+ // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_2:.*]]
+ List[i] = i * 2;
+ i++;
+ } while (i < Length);
+}
+
+// Verify for loop is recognized after unroll pragma.
+void for_test(int *List, int Length) {
+// CHECK: define {{.*}} @_Z8for_test
+#pragma unroll 8
+ for (int i = 0; i < Length; i++) {
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_3:.*]]
+ List[i] = i * 2;
+ }
+}
+
+// Verify c++11 for range loop is recognized after unroll pragma.
+void for_range_test() {
+ // CHECK: define {{.*}} @_Z14for_range_test
+ double List[100];
+
+#pragma unroll(4)
+ for (int i : List) {
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_4:.*]]
+ List[i] = i;
+ }
+}
+
+#define UNROLLCOUNT 8
+
+// Verify defines are correctly resolved in unroll pragmas.
+void for_define_test(int *List, int Length, int Value) {
+// CHECK: define {{.*}} @_Z15for_define_test
+#pragma unroll(UNROLLCOUNT)
+ for (int i = 0; i < Length; i++) {
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_5:.*]]
+ List[i] = i * Value;
+ }
+}
+
+// Verify metadata is generated when template is used.
+template <typename A>
+void for_template_test(A *List, int Length, A Value) {
+// CHECK: define {{.*}} @_Z13template_test
+#pragma unroll 8
+ for (int i = 0; i < Length; i++) {
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_6:.*]]
+ List[i] = i * Value;
+ }
+}
+
+// Verify define is resolved correctly when template is used.
+template <typename A>
+void for_template_define_test(A *List, int Length, A Value) {
+// CHECK: define {{.*}} @_Z24for_template_define_test
+
+#pragma unroll(UNROLLCOUNT)
+ for (int i = 0; i < Length; i++) {
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_7:.*]]
+ List[i] = i * Value;
+ }
+}
+
+#undef UNROLLCOUNT
+
+// Use templates defined above. Test verifies metadata is generated correctly.
+void template_test(double *List, int Length) {
+ double Value = 10;
+
+ for_template_test<double>(List, Length, Value);
+ for_template_define_test<double>(List, Length, Value);
+}
+
+// CHECK: ![[LOOP_1]] = distinct !{![[LOOP_1]], ![[UNROLL_ENABLE:.*]]}
+// CHECK: ![[UNROLL_ENABLE]] = !{!"llvm.loop.unroll.enable"}
+// CHECK: ![[LOOP_2]] = distinct !{![[LOOP_2:.*]], ![[UNROLL_DISABLE:.*]]}
+// CHECK: ![[UNROLL_DISABLE]] = !{!"llvm.loop.unroll.disable"}
+// CHECK: ![[LOOP_3]] = distinct !{![[LOOP_3]], ![[UNROLL_8:.*]]}
+// CHECK: ![[UNROLL_8]] = !{!"llvm.loop.unroll.count", i32 8}
+// CHECK: ![[LOOP_4]] = distinct !{![[LOOP_4]], ![[UNROLL_4:.*]]}
+// CHECK: ![[UNROLL_4]] = !{!"llvm.loop.unroll.count", i32 4}
+// CHECK: ![[LOOP_5]] = distinct !{![[LOOP_5]], ![[UNROLL_8:.*]]}
+// CHECK: ![[LOOP_6]] = distinct !{![[LOOP_6]], ![[UNROLL_8:.*]]}
+// CHECK: ![[LOOP_7]] = distinct !{![[LOOP_7]], ![[UNROLL_8:.*]]}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/pragma-visibility.cpp b/src/llvm-project/clang/test/CodeGenCXX/pragma-visibility.cpp
new file mode 100644
index 0000000..c0ba904
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/pragma-visibility.cpp
@@ -0,0 +1,74 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -o - %s | FileCheck %s
+
+#pragma GCC visibility push(hidden)
+struct x {
+ static int y;
+};
+#pragma GCC visibility pop
+int x::y = 10;
+// CHECK: @_ZN1x1yE = hidden global
+
+#pragma GCC visibility push(hidden)
+struct __attribute((visibility("default"))) x2 {
+ static int y;
+};
+int x2::y = 10;
+// CHECK: @_ZN2x21yE = global
+#pragma GCC visibility pop
+
+#pragma GCC visibility push(hidden)
+template<class T> struct x4 {
+ static int y;
+};
+#pragma GCC visibility pop
+template<> int x4<int>::y = 10;
+// CHECK: @_ZN2x4IiE1yE = hidden global i32
+
+#pragma GCC visibility push(hidden)
+template<int x> int f() { return x; }
+extern "C" int g() { return f<3>(); }
+#pragma GCC visibility pop
+// CHECK-LABEL: define hidden i32 @g()
+// CHECK-LABEL: define linkonce_odr hidden i32 @_Z1fILi3EEiv()
+
+#pragma GCC visibility push(hidden)
+template<class T> struct x5 {
+ void y();
+};
+#pragma GCC visibility pop
+template<> void x5<int>::y() {}
+// CHECK-LABEL: define hidden void @_ZN2x5IiE1yEv
+
+#pragma GCC visibility push(hidden)
+namespace n __attribute((visibility("default"))) {
+ void f() {}
+ // CHECK-LABEL: define void @_ZN1n1fEv
+}
+#pragma GCC visibility pop
+
+namespace n __attribute((visibility("default"))) {
+#pragma GCC visibility push(hidden)
+ void g() {}
+ // CHECK-LABEL: define hidden void @_ZN1n1gEv
+#pragma GCC visibility pop
+}
+
+namespace test2 {
+#pragma GCC visibility push(default)
+#pragma GCC visibility push(hidden)
+ struct foo { // foo is hidden
+ };
+#pragma GCC visibility pop
+ struct foo; // declaration is ok, we ignore the default in the stack
+ template<typename T>
+ struct bar { // bar is default
+ static void f(){}
+ };
+#pragma GCC visibility pop
+ void zed() {
+ bar<foo>::f();
+ bar<int>::f();
+ }
+ // CHECK-LABEL: define linkonce_odr hidden void @_ZN5test23barINS_3fooEE1fEv
+ // CHECK-LABEL: define linkonce_odr void @_ZN5test23barIiE1fEv
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/pragma-weak.cpp b/src/llvm-project/clang/test/CodeGenCXX/pragma-weak.cpp
new file mode 100644
index 0000000..83d66bc
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/pragma-weak.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s
+
+#pragma weak zex
+int zex;
+// GCC produces a weak symbol for this because it matches mangled names.
+// Different c++ ABIs may or may not mangle this, so we produce a strong
+// symbol.
+// CHECK: @zex = {{(dso_local )?}}global i32
+
+#pragma weak foo
+struct S { void foo(); };
+void S::foo() {}
+// CHECK-LABEL: define {{.*}}void @_ZN1S3fooEv(
+
+#pragma weak zed
+namespace bar { void zed() {} }
+// CHECK-LABEL: define {{.*}}void @_ZN3bar3zedEv(
+
+#pragma weak bah
+void bah() {}
+// CHECK-LABEL: define {{.*}}void @_Z3bahv(
+
+#pragma weak baz
+extern "C" void baz() {}
+// CHECK-LABEL: define weak {{.*}}void @baz(
+
+#pragma weak _Z3baxv
+void bax() {}
+// GCC produces a weak symbol for this one, but it doesn't look like a good
+// idea to expose the mangling to the pragma unless we really have to.
+// CHECK-LABEL: define {{.*}}void @_Z3baxv(
diff --git a/src/llvm-project/clang/test/CodeGenCXX/predefined-expr-cxx14.cpp b/src/llvm-project/clang/test/CodeGenCXX/predefined-expr-cxx14.cpp
new file mode 100644
index 0000000..dd531e3
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/predefined-expr-cxx14.cpp
@@ -0,0 +1,105 @@
+// RUN: %clang_cc1 -std=c++14 %s -triple %itanium_abi_triple -fblocks -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -x c++ -std=c++14 -triple %itanium_abi_triple -fblocks -emit-pch -o %t %s
+// RUN: %clang_cc1 -x c++ -triple %itanium_abi_triple -std=c++14 -fblocks -include-pch %t %s -emit-llvm -o - | FileCheck %s
+
+#ifndef HEADER
+#define HEADER
+
+// CHECK-DAG: @__func__._ZN13ClassTemplateIiE21classTemplateFunctionERi = private unnamed_addr constant [22 x i8] c"classTemplateFunction\00"
+// CHECK-DAG: @__PRETTY_FUNCTION__._ZN13ClassTemplateIiE21classTemplateFunctionERi = private unnamed_addr constant [69 x i8] c"const auto &ClassTemplate<int>::classTemplateFunction(T &) [T = int]\00"
+
+// CHECK-DAG: @__func__._ZN24ClassInTopLevelNamespace16functionTemplateIiEERDaRT_ = private unnamed_addr constant [17 x i8] c"functionTemplate\00"
+// CHECK-DAG: @__PRETTY_FUNCTION__._ZN24ClassInTopLevelNamespace16functionTemplateIiEERDaRT_ = private unnamed_addr constant [64 x i8] c"auto &ClassInTopLevelNamespace::functionTemplate(T &) [T = int]\00"
+
+// CHECK-DAG: @__func__._ZN24ClassInTopLevelNamespace16variadicFunctionEPiz = private unnamed_addr constant [17 x i8] c"variadicFunction\00"
+// CHECK-DAG: @__PRETTY_FUNCTION__._ZN24ClassInTopLevelNamespace16variadicFunctionEPiz = private unnamed_addr constant [70 x i8] c"decltype(auto) ClassInTopLevelNamespace::variadicFunction(int *, ...)\00"
+
+// CHECK-DAG: @__func__._ZN24ClassInTopLevelNamespace25topLevelNamespaceFunctionEv = private unnamed_addr constant [26 x i8] c"topLevelNamespaceFunction\00"
+// CHECK-DAG: @__PRETTY_FUNCTION__._ZN24ClassInTopLevelNamespace25topLevelNamespaceFunctionEv = private unnamed_addr constant [60 x i8] c"auto *ClassInTopLevelNamespace::topLevelNamespaceFunction()\00"
+
+// CHECK-DAG: @__func__.___ZN16ClassBlockConstrD2Ev_block_invoke = private unnamed_addr constant [31 x i8] c"~ClassBlockConstr_block_invoke\00"
+// CHECK-DAG: @__func__.___ZN16ClassBlockConstrC2Ev_block_invoke = private unnamed_addr constant [30 x i8] c"ClassBlockConstr_block_invoke\00"
+
+int printf(const char * _Format, ...);
+
+class ClassInTopLevelNamespace {
+public:
+ auto *topLevelNamespaceFunction() {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ return static_cast<int *>(nullptr);
+ }
+
+ decltype(auto) variadicFunction(int *a, ...) {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ return a;
+ }
+
+ template<typename T>
+ auto &functionTemplate(T &t) {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ return t;
+ }
+};
+
+template<typename T>
+class ClassTemplate {
+public:
+ const auto &classTemplateFunction(T &t) {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ return t;
+ }
+};
+
+struct ClassBlockConstr {
+ const char *s;
+ ClassBlockConstr() {
+ const char * (^b)() = ^() {
+ return __func__;
+ };
+ s = b();
+ }
+ ~ClassBlockConstr() {
+ const char * (^b)() = ^() {
+ return __func__;
+ };
+ s = b();
+ }
+};
+
+template <class T>
+class FuncTemplate {
+ const char *Func;
+
+public:
+ FuncTemplate() : Func(__func__) {}
+ const char *getFunc() const { return Func; }
+};
+
+int
+main() {
+ int a;
+ ClassInTopLevelNamespace topLevelNamespace;
+ ClassBlockConstr classBlockConstr;
+ topLevelNamespace.topLevelNamespaceFunction();
+ topLevelNamespace.variadicFunction(&a);
+ topLevelNamespace.functionTemplate(a);
+
+ ClassTemplate<int> t;
+ t.classTemplateFunction(a);
+ return 0;
+}
+#else
+void Foo() {
+ FuncTemplate<int> FTi;
+ (void)FTi.getFunc();
+}
+#endif
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/predefined-expr-sizeof.cpp b/src/llvm-project/clang/test/CodeGenCXX/predefined-expr-sizeof.cpp
new file mode 100644
index 0000000..b4712ad
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/predefined-expr-sizeof.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+
+// CHECK: store i32 59, i32* %size
+// CHECK: store i32 65, i32* %size
+template<typename T>
+class TemplateClass {
+public:
+ void templateClassFunction() {
+ int size = sizeof(__PRETTY_FUNCTION__);
+ }
+};
+
+// CHECK: store i32 35, i32* %size
+// CHECK: store i32 38, i32* %size
+template<typename T>
+void functionTemplate(T t) {
+ int size = sizeof(__PRETTY_FUNCTION__);
+}
+
+int main() {
+ TemplateClass<int> t1;
+ t1.templateClassFunction();
+ TemplateClass<double> t2;
+ t2.templateClassFunction();
+
+ functionTemplate<int>(0);
+ functionTemplate(0.0);
+
+ return 0;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/predefined-expr.cpp b/src/llvm-project/clang/test/CodeGenCXX/predefined-expr.cpp
new file mode 100644
index 0000000..21ccedd
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/predefined-expr.cpp
@@ -0,0 +1,569 @@
+// RUN: %clang_cc1 -std=c++11 -fblocks %s -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %s
+
+// CHECK-DAG: private unnamed_addr constant [15 x i8] c"externFunction\00"
+// CHECK-DAG: private unnamed_addr constant [26 x i8] c"void NS::externFunction()\00"
+// CHECK-DAG: private unnamed_addr constant [49 x i8] c"void functionTemplateExplicitSpecialization(int)\00"
+
+// CHECK-DAG: private unnamed_addr constant [95 x i8] c"void SpecializedClassTemplate<char>::memberFunctionTemplate(T, U) const [T = char, U = double]\00"
+// CHECK-DAG: private unnamed_addr constant [85 x i8] c"void SpecializedClassTemplate<int>::memberFunctionTemplate(int, U) const [U = float]\00"
+// CHECK-DAG: private unnamed_addr constant [57 x i8] c"void NonTypeTemplateParam<42>::size() const [Count = 42]\00"
+// CHECK-DAG: private unnamed_addr constant [122 x i8] c"static void ClassWithTemplateTemplateParam<char, NS::ClassTemplate>::staticMember() [T = char, Param = NS::ClassTemplate]\00"
+// CHECK-DAG: private unnamed_addr constant [106 x i8] c"void OuterClass<int *>::MiddleClass::InnerClass<float>::memberFunction(T, U) const [T = int *, U = float]\00"
+// CHECK-DAG: private unnamed_addr constant [51 x i8] c"void functionTemplateWithCapturedStmt(T) [T = int]\00"
+// CHECK-DAG: private unnamed_addr constant [76 x i8] c"auto functionTemplateWithLambda(int)::(anonymous class)::operator()() const\00"
+// CHECK-DAG: private unnamed_addr constant [65 x i8] c"void functionTemplateWithUnnamedTemplateParameter(T) [T = float]\00"
+
+// CHECK-DAG: private unnamed_addr constant [60 x i8] c"void functionTemplateExplicitSpecialization(T) [T = double]\00"
+// CHECK-DAG: private unnamed_addr constant [52 x i8] c"T *functionTemplateWithCompoundTypes(T *) [T = int]\00"
+// CHECK-DAG: private unnamed_addr constant [54 x i8] c"T functionTemplateWithTemplateReturnType() [T = char]\00"
+// CHECK-DAG: private unnamed_addr constant [57 x i8] c"void functionTemplateWithoutParameterList() [T = double]\00"
+// CHECK-DAG: private unnamed_addr constant [62 x i8] c"void functionTemplateWithTwoParams(T, U) [T = int, U = float]\00"
+
+// CHECK-DAG: private unnamed_addr constant [22 x i8] c"classTemplateFunction\00"
+// CHECK-DAG: private unnamed_addr constant [77 x i8] c"void NS::ClassTemplate<NS::Base *>::classTemplateFunction() [T = NS::Base *]\00"
+// CHECK-DAG: private unnamed_addr constant [63 x i8] c"void NS::ClassTemplate<int>::classTemplateFunction() [T = int]\00"
+
+// CHECK-DAG: private unnamed_addr constant [18 x i8] c"functionTemplate1\00"
+// CHECK-DAG: private unnamed_addr constant [53 x i8] c"void NS::Base::functionTemplate1(T) [T = NS::Base *]\00"
+// CHECK-DAG: private unnamed_addr constant [46 x i8] c"void NS::Base::functionTemplate1(T) [T = int]\00"
+
+// CHECK-DAG: private unnamed_addr constant [23 x i8] c"anonymousUnionFunction\00"
+// CHECK-DAG: private unnamed_addr constant [83 x i8] c"void NS::ContainerForAnonymousRecords::(anonymous union)::anonymousUnionFunction()\00"
+
+// CHECK-DAG: private unnamed_addr constant [24 x i8] c"anonymousStructFunction\00"
+// CHECK-DAG: private unnamed_addr constant [85 x i8] c"void NS::ContainerForAnonymousRecords::(anonymous struct)::anonymousStructFunction()\00"
+
+// CHECK-DAG: private unnamed_addr constant [23 x i8] c"anonymousClassFunction\00"
+// CHECK-DAG: private unnamed_addr constant [83 x i8] c"void NS::ContainerForAnonymousRecords::(anonymous class)::anonymousClassFunction()\00"
+
+// CHECK-DAG: private unnamed_addr constant [12 x i8] c"~Destructor\00"
+// CHECK-DAG: private unnamed_addr constant [30 x i8] c"NS::Destructor::~Destructor()\00"
+
+// CHECK-DAG: private unnamed_addr constant [12 x i8] c"Constructor\00"
+// CHECK-DAG: private unnamed_addr constant [41 x i8] c"NS::Constructor::Constructor(NS::Base *)\00"
+// CHECK-DAG: private unnamed_addr constant [34 x i8] c"NS::Constructor::Constructor(int)\00"
+// CHECK-DAG: private unnamed_addr constant [31 x i8] c"NS::Constructor::Constructor()\00"
+
+// CHECK-DAG: private unnamed_addr constant [16 x i8] c"virtualFunction\00"
+// CHECK-DAG: private unnamed_addr constant [44 x i8] c"virtual void NS::Derived::virtualFunction()\00"
+
+// CHECK-DAG: private unnamed_addr constant [21 x i8] c"refQualifiedFunction\00"
+// CHECK-DAG: private unnamed_addr constant [41 x i8] c"void NS::Base::refQualifiedFunction() &&\00"
+// CHECK-DAG: private unnamed_addr constant [40 x i8] c"void NS::Base::refQualifiedFunction() &\00"
+
+// CHECK-DAG: private unnamed_addr constant [22 x i8] c"constVolatileFunction\00"
+// CHECK-DAG: private unnamed_addr constant [54 x i8] c"void NS::Base::constVolatileFunction() const volatile\00"
+
+// CHECK-DAG: private unnamed_addr constant [17 x i8] c"volatileFunction\00"
+// CHECK-DAG: private unnamed_addr constant [43 x i8] c"void NS::Base::volatileFunction() volatile\00"
+
+// CHECK-DAG: private unnamed_addr constant [14 x i8] c"constFunction\00"
+// CHECK-DAG: private unnamed_addr constant [37 x i8] c"void NS::Base::constFunction() const\00"
+
+// CHECK-DAG: private unnamed_addr constant [26 x i8] c"functionReturingTemplate2\00"
+// CHECK-DAG: private unnamed_addr constant [64 x i8] c"ClassTemplate<NS::Base *> NS::Base::functionReturingTemplate2()\00"
+
+// CHECK-DAG: private unnamed_addr constant [26 x i8] c"functionReturingTemplate1\00"
+// CHECK-DAG: private unnamed_addr constant [57 x i8] c"ClassTemplate<int> NS::Base::functionReturingTemplate1()\00"
+
+// CHECK-DAG: private unnamed_addr constant [23 x i8] c"withTemplateParameter2\00"
+// CHECK-DAG: private unnamed_addr constant [65 x i8] c"void NS::Base::withTemplateParameter2(ClassTemplate<NS::Base *>)\00"
+
+// CHECK-DAG: private unnamed_addr constant [23 x i8] c"withTemplateParameter1\00"
+// CHECK-DAG: private unnamed_addr constant [58 x i8] c"void NS::Base::withTemplateParameter1(ClassTemplate<int>)\00"
+
+// CHECK-DAG: private unnamed_addr constant [23 x i8] c"functionReturningClass\00"
+// CHECK-DAG: private unnamed_addr constant [45 x i8] c"NS::Base *NS::Base::functionReturningClass()\00"
+
+// CHECK-DAG: private unnamed_addr constant [23 x i8] c"functionWithParameters\00"
+// CHECK-DAG: private unnamed_addr constant [64 x i8] c"void NS::Base::functionWithParameters(int, float *, NS::Base *)\00"
+
+// CHECK-DAG: private unnamed_addr constant [17 x i8] c"variadicFunction\00"
+// CHECK-DAG: private unnamed_addr constant [42 x i8] c"void NS::Base::variadicFunction(int, ...)\00"
+
+// CHECK-DAG: private unnamed_addr constant [41 x i8] c"virtual void NS::Base::virtualFunction()\00"
+
+// CHECK-DAG: private unnamed_addr constant [15 x i8] c"inlineFunction\00"
+// CHECK-DAG: private unnamed_addr constant [32 x i8] c"void NS::Base::inlineFunction()\00"
+
+// CHECK-DAG: private unnamed_addr constant [15 x i8] c"staticFunction\00"
+// CHECK-DAG: private unnamed_addr constant [39 x i8] c"static void NS::Base::staticFunction()\00"
+
+// CHECK-DAG: private unnamed_addr constant [26 x i8] c"topLevelNamespaceFunction\00"
+// CHECK-DAG: private unnamed_addr constant [59 x i8] c"void ClassInTopLevelNamespace::topLevelNamespaceFunction()\00"
+
+// CHECK-DAG: private unnamed_addr constant [27 x i8] c"anonymousNamespaceFunction\00"
+// CHECK-DAG: private unnamed_addr constant [84 x i8] c"void (anonymous namespace)::ClassInAnonymousNamespace::anonymousNamespaceFunction()\00"
+
+// CHECK-DAG: private unnamed_addr constant [19 x i8] c"localClassFunction\00"
+// CHECK-DAG: private unnamed_addr constant [59 x i8] c"void NS::localClass(int)::LocalClass::localClassFunction()\00"
+
+
+
+int printf(const char * _Format, ...);
+
+class ClassInTopLevelNamespace {
+public:
+ void topLevelNamespaceFunction() {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ }
+};
+
+namespace {
+
+ class ClassInAnonymousNamespace {
+ public:
+ void anonymousNamespaceFunction() {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ }
+ };
+
+} // end anonymous namespace
+
+namespace NS {
+
+template<typename T>
+class ClassTemplate {
+public:
+ void classTemplateFunction() {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ }
+};
+
+class Base {
+public:
+ static void staticFunction() {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ }
+
+ inline void (inlineFunction)() {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ }
+
+ virtual void virtualFunction() {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ }
+
+ void functionWithParameters(int, float*, Base* base) {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ }
+
+ Base *functionReturningClass() {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ return 0;
+ }
+
+ void variadicFunction(int, ...) {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ }
+
+ void withTemplateParameter1(ClassTemplate<int>) {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ }
+
+ void withTemplateParameter2(ClassTemplate<Base *>) {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ }
+
+ ClassTemplate<int> functionReturingTemplate1() {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ return ClassTemplate<int>();
+ }
+
+ ClassTemplate<Base *> functionReturingTemplate2() {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ return ClassTemplate<Base *>();
+ }
+
+ template<typename T>
+ void functionTemplate1(T t) {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ }
+
+ void constFunction() const {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ }
+
+ void volatileFunction() volatile {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ }
+
+ void constVolatileFunction() const volatile {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ }
+
+ void refQualifiedFunction() & {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ }
+
+ void refQualifiedFunction() && {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ }
+};
+
+class Derived : public Base {
+public:
+ // Virtual function without being explicitly written.
+ void virtualFunction() {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ }
+};
+
+class Constructor {
+public:
+ Constructor() {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ }
+
+ Constructor(int) {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ }
+
+ Constructor(Base *) {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ }
+};
+
+class Destructor {
+public:
+ ~Destructor() {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ }
+};
+
+class ContainerForAnonymousRecords {
+public:
+ class {
+ public:
+ void anonymousClassFunction() {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ }
+ } anonymousClass;
+
+ struct {
+ void anonymousStructFunction() {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ }
+ } anonymousStruct;
+
+ union {
+ void anonymousUnionFunction() {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ }
+ } anonymousUnion;
+};
+
+void localClass(int) {
+ class LocalClass {
+ public:
+ void localClassFunction() {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ }
+ };
+ LocalClass lc;
+ lc.localClassFunction();
+}
+
+extern void externFunction() {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+}
+
+} // end NS namespace
+
+// additional tests for __PRETTY_FUNCTION__
+template <typename T, typename U>
+void functionTemplateWithTwoParams(T, U)
+{
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+}
+
+template <typename T>
+void functionTemplateWithoutParameterList()
+{
+ T t = T();
+
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+}
+
+template <typename T>
+T functionTemplateWithTemplateReturnType()
+{
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+
+ return T();
+}
+
+template <typename T>
+T * functionTemplateWithCompoundTypes(T a[])
+{
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+
+ return 0;
+}
+
+template <typename T>
+void functionTemplateExplicitSpecialization(T t)
+{
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+}
+
+template <>
+void functionTemplateExplicitSpecialization<int>(int i)
+{
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+}
+
+template <typename, typename T>
+void functionTemplateWithUnnamedTemplateParameter(T t)
+{
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+}
+
+template <typename T>
+void functionTemplateWithLambda(T t)
+{
+ []() {
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ } ();
+}
+
+template <typename T>
+void functionTemplateWithCapturedStmt(T t)
+{
+ #pragma clang __debug captured
+ {
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ }
+}
+
+template <typename T>
+class OuterClass
+{
+public:
+ class MiddleClass
+ {
+ public:
+ template <typename U>
+ class InnerClass
+ {
+ public:
+ void memberFunction(T x, U y) const
+ {
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ }
+ };
+ };
+};
+
+template <typename T, template <typename> class Param = NS::ClassTemplate>
+class ClassWithTemplateTemplateParam
+{
+public:
+ static void staticMember()
+ {
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ }
+};
+
+template <int Count>
+class NonTypeTemplateParam
+{
+public:
+ void size() const
+ {
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ }
+};
+
+template <typename T>
+class SpecializedClassTemplate
+{
+public:
+ template <typename U>
+ void memberFunctionTemplate(T t, U u) const
+ {
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ }
+};
+
+template <>
+class SpecializedClassTemplate<int>
+{
+public:
+ template <typename U>
+ void memberFunctionTemplate(int i, U u) const
+ {
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ }
+};
+
+int main() {
+ ClassInAnonymousNamespace anonymousNamespace;
+ anonymousNamespace.anonymousNamespaceFunction();
+
+ ClassInTopLevelNamespace topLevelNamespace;
+ topLevelNamespace.topLevelNamespaceFunction();
+
+ NS::Base::staticFunction();
+
+ NS::Base b;
+ b.inlineFunction();
+ b.virtualFunction();
+ b.variadicFunction(0);
+ b.functionWithParameters(0, 0, 0);
+ b.functionReturningClass();
+
+ b.withTemplateParameter1(NS::ClassTemplate<int>());
+ b.withTemplateParameter2(NS::ClassTemplate<NS::Base *>());
+ b.functionReturingTemplate1();
+ b.functionReturingTemplate2();
+ b.functionTemplate1<int>(0);
+ b.functionTemplate1<NS::Base *>(0);
+ b.constFunction();
+ b.volatileFunction();
+ b.constVolatileFunction();
+ b.refQualifiedFunction();
+ NS::Base().refQualifiedFunction();
+
+ NS::Derived d;
+ d.virtualFunction();
+
+ NS::ClassTemplate<int> t1;
+ t1.classTemplateFunction();
+ NS::ClassTemplate<NS::Base *> t2;
+ t2.classTemplateFunction();
+
+ NS::Constructor c1;
+ NS::Constructor c2(0);
+ NS::Constructor c3((NS::Base *)0);
+
+ {
+ NS::Destructor destructor;
+ }
+
+ NS::ContainerForAnonymousRecords anonymous;
+ anonymous.anonymousClass.anonymousClassFunction();
+ anonymous.anonymousStruct.anonymousStructFunction();
+ anonymous.anonymousUnion.anonymousUnionFunction();
+
+ NS::localClass(0);
+
+ NS::externFunction();
+
+ // additional tests for __PRETTY_FUNCTION__
+
+ functionTemplateWithTwoParams(0, 0.0f);
+ functionTemplateWithoutParameterList<double>();
+ functionTemplateWithTemplateReturnType<char>();
+ int array[] = { 1, 2, 3 };
+ functionTemplateWithCompoundTypes(array);
+ functionTemplateExplicitSpecialization(0);
+ functionTemplateExplicitSpecialization(0.0);
+ functionTemplateWithUnnamedTemplateParameter<int, float>(0.0f);
+
+ functionTemplateWithLambda<int>(0);
+ functionTemplateWithCapturedStmt<int>(0);
+
+ OuterClass<int *>::MiddleClass::InnerClass<float> omi;
+ omi.memberFunction(0, 0.0f);
+
+ ClassWithTemplateTemplateParam<char>::staticMember();
+
+ NonTypeTemplateParam<42> ntt;
+ ntt.size();
+
+ SpecializedClassTemplate<int> sct1;
+ sct1.memberFunctionTemplate(0, 0.0f);
+ SpecializedClassTemplate<char> sct2;
+ sct2.memberFunctionTemplate('0', 0.0);
+
+ return 0;
+}
+
+// rdar://19065361
+class XXX {
+ XXX();
+ ~XXX();
+};
+
+void XXLog(const char *functionName) { }
+
+typedef void (^notify_handler_t)(int token);
+
+typedef void (^dispatch_block_t)(void);
+
+void notify_register_dispatch(notify_handler_t handler);
+
+void _dispatch_once(dispatch_block_t block);
+
+XXX::XXX()
+{
+ _dispatch_once(^{ notify_register_dispatch( ^(int token) { XXLog(__FUNCTION__); });
+ });
+}
+// CHECK: define internal {{.*}}void @___ZN3XXXC2Ev_block_invoke_
+
+XXX::~XXX()
+{
+ _dispatch_once(^{ notify_register_dispatch( ^(int token) { XXLog(__FUNCTION__); });
+ });
+}
+// CHECK: define internal {{.*}}void @___ZN3XXXD2Ev_block_invoke_
diff --git a/src/llvm-project/clang/test/CodeGenCXX/profile-remap.cpp b/src/llvm-project/clang/test/CodeGenCXX/profile-remap.cpp
new file mode 100644
index 0000000..0fc7c7b
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/profile-remap.cpp
@@ -0,0 +1,29 @@
+// REQUIRES: x86-registered-target
+//
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -fprofile-sample-use=%S/Inputs/profile-remap.samples -fprofile-remapping-file=%S/Inputs/profile-remap.map -fexperimental-new-pass-manager -O2 %s -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,CHECK-SAMPLES
+// RUN: llvm-profdata merge -output %T.profdata %S/Inputs/profile-remap.proftext
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -fprofile-instrument-use-path=%T.profdata -fprofile-remapping-file=%S/Inputs/profile-remap.map -fexperimental-new-pass-manager -O2 %s -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,CHECK-INSTR
+
+namespace Foo {
+ struct X {};
+ bool cond();
+ void bar();
+ void baz();
+ void function(X x) {
+ if (cond())
+ bar();
+ else
+ baz();
+ }
+}
+
+// CHECK: define {{.*}} @_ZN3Foo8functionENS_1XE() {{.*}} !prof [[FUNC_ENTRY:![0-9]*]]
+// CHECK: br i1 {{.*}} !prof [[BR_WEIGHTS:![0-9]*]]
+//
+// FIXME: Laplace's rule of succession is applied to sample profiles...
+// CHECK-SAMPLES-DAG: [[FUNC_ENTRY]] = !{!"function_entry_count", i64 1}
+// CHECK-SAMPLES-DAG: [[BR_WEIGHTS]] = !{!"branch_weights", i32 11, i32 91}
+//
+// ... but not to instruction profiles.
+// CHECK-INSTR-DAG: [[FUNC_ENTRY]] = !{!"function_entry_count", i64 100}
+// CHECK-INSTR-DAG: [[BR_WEIGHTS]] = !{!"branch_weights", i32 10, i32 90}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/ptr-to-datamember.cpp b/src/llvm-project/clang/test/CodeGenCXX/ptr-to-datamember.cpp
new file mode 100644
index 0000000..a6f523e
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/ptr-to-datamember.cpp
@@ -0,0 +1,99 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s
+
+extern "C" int printf(...);
+
+struct F {
+ F() : iF(1), fF(2.0) {}
+ int iF;
+ float fF;
+};
+
+struct V {
+ double d;
+ int iV;
+};
+
+struct B : virtual V{
+ double d;
+ int iB;
+};
+
+struct B1 : virtual V{
+ double d;
+ int iB1;
+};
+
+class A : public B, public B1 {
+public:
+ A() : f(1.0), d(2.0), Ai(3) {}
+ float f;
+ double d;
+ int Ai;
+ F Af;
+};
+
+template <typename T> struct TT {
+ int T::t::*pti;
+};
+
+struct I {
+ typedef I t;
+ int x;
+};
+
+void pr(const F& b) {
+ printf(" %d %f\n", b.iF, b.fF);
+}
+
+void test_aggr_pdata(A& a1) {
+ F A::* af = &A::Af;
+ pr(a1.*af);
+
+ (a1.*af).iF = 100;
+ (a1.*af).fF = 200.00;
+ printf(" %d %f\n", (a1.*af).iF, (a1.*af).fF);
+ pr(a1.*af);
+
+ (a1.*af).iF++;
+ (a1.*af).fF--;
+ --(a1.*af).fF;
+ pr(a1.*af);
+}
+
+void test_aggr_pdata_1(A* pa) {
+ F A::* af = &A::Af;
+ pr(pa->*af);
+
+ (pa->*af).iF = 100;
+ (pa->*af).fF = 200.00;
+ printf(" %d %f\n", (pa->*af).iF, (pa->*af).fF);
+ pr(pa->*af);
+
+ (pa->*af).iF++;
+ (pa->*af).fF--;
+ --(pa->*af).fF;
+ pr(pa->*af);
+}
+
+int main()
+{
+ A a1;
+ TT<I> tt;
+ I i;
+ int A::* pa = &A::Ai;
+ float A::* pf = &A::f;
+ double A::* pd = &A::d;
+ tt.pti = &I::x;
+ printf("%d %d %d\n", &A::Ai, &A::f, &A::d);
+ printf("%d\n", &A::B::iB);
+ printf("%d\n", &A::B1::iB1);
+ printf("%d\n", &A::f);
+ printf("%d\n", &A::B::iV);
+ printf("%d\n", &A::B1::iV);
+ printf("%d\n", &A::B::V::iV);
+ printf("%d\n", &A::B1::V::iV);
+ printf("%d, %f, %f \n", a1.*pa, a1.*pf, a1.*pd);
+ printf("%d\n", i.*tt.pti);
+ test_aggr_pdata(a1);
+ test_aggr_pdata_1(&a1);
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/ptr-to-member-function.cpp b/src/llvm-project/clang/test/CodeGenCXX/ptr-to-member-function.cpp
new file mode 100644
index 0000000..e02b209
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/ptr-to-member-function.cpp
@@ -0,0 +1,70 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm %s -o - | \
+// RUN: FileCheck -check-prefix CHECK-LP64 %s
+// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -emit-llvm %s -o - | \
+// RUN: FileCheck -check-prefix CHECK-LP32 %s
+// 13.3.3.2 Ranking implicit conversion sequences
+
+extern "C" int printf(...);
+
+struct A {
+int Ai;
+bool foo(int* arg) const;
+};
+
+bool A::foo(int* arg) const {
+ printf("A::foo(%d)\n", *arg);
+ return true;
+}
+
+struct B : public A {
+ void bf() { printf("B::bf called\n"); }
+};
+
+struct C : public B { };
+
+// conversion of B::* to C::* is better than conversion of A::* to C::*
+typedef void (A::*pmfa)();
+typedef void (B::*pmfb)();
+typedef void (C::*pmfc)();
+
+struct X {
+ operator pmfa();
+ operator pmfb() {
+ return &B::bf;
+ }
+};
+
+
+void g(pmfc pm) {
+ C c;
+ (c.*pm)();
+}
+
+void test2(X x)
+{
+ g(x);
+}
+
+struct B1 {
+ bool (A::*pmf)(int*) const;
+
+ B1(int i) : pmf(&A::foo), im(i) {
+ ((A*)this->*pmf)(&im);
+ }
+
+ int im;
+};
+
+int main()
+{
+ X x;
+ test2(x);
+ B1 b = B1(1);
+ B1 c = B1(2);
+}
+
+// CHECK-LP64: call { i64, i64 } @_ZN1XcvM1BFvvEEv
+// CHECK-LP64: call void @_Z1gM1CFvvE
+
+// CHECK-LP32: call i64 @_ZN1XcvM1BFvvEEv
+// CHECK-LP32: call void @_Z1gM1CFvvE
diff --git a/src/llvm-project/clang/test/CodeGenCXX/redefine_extname.cpp b/src/llvm-project/clang/test/CodeGenCXX/redefine_extname.cpp
new file mode 100644
index 0000000..41860d4
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/redefine_extname.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -triple=i386-pc-solaris2.11 -w -emit-llvm %s -o - | FileCheck %s
+
+extern "C" {
+ struct statvfs64 {
+ int f;
+ };
+#pragma redefine_extname statvfs64 statvfs
+ int statvfs64(struct statvfs64 *);
+}
+
+void some_func() {
+ struct statvfs64 st;
+ statvfs64(&st);
+// Check that even if there is a structure with redefined name before the
+// pragma, subsequent function name redefined properly. PR5172, Comment 11.
+// CHECK: call i32 @statvfs(%struct.statvfs64* %st)
+}
+
+// This is a case when redefenition is deferred *and* we have a local of the
+// same name. PR23923.
+#pragma redefine_extname foo bar
+int f() {
+ int foo = 0;
+ return foo;
+}
+extern "C" {
+ int foo() { return 1; }
+// CHECK: define i32 @bar()
+}
+
+// Check that #pragma redefine_extname applies to C code only, and shouldn't be
+// applied to C++.
+#pragma redefine_extname foo_cpp bar_cpp
+extern int foo_cpp() { return 1; }
+// CHECK-NOT: define i32 @bar_cpp()
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/reference-bind-default-argument.cpp b/src/llvm-project/clang/test/CodeGenCXX/reference-bind-default-argument.cpp
new file mode 100644
index 0000000..5cf279f
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/reference-bind-default-argument.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 %s -emit-llvm-only -verify
+// expected-no-diagnostics
+
+struct A {};
+struct B : A {};
+void a(const A& x = B());
+void b() { a(); }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/reference-cast.cpp b/src/llvm-project/clang/test/CodeGenCXX/reference-cast.cpp
new file mode 100644
index 0000000..54faa64
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/reference-cast.cpp
@@ -0,0 +1,196 @@
+// RUN: %clang_cc1 -emit-llvm -triple x86_64-apple-darwin10 -o - %s | FileCheck %s
+
+// PR6024
+extern int i;
+
+// CHECK: define dereferenceable({{[0-9]+}}) i32* @_Z16lvalue_noop_castv() [[NUW:#[0-9]+]]
+const int &lvalue_noop_cast() {
+ if (i == 0)
+ // CHECK: store i32 17, i32*
+ return (const int&)17;
+ else if (i == 1)
+ // CHECK: store i32 17, i32*
+ return static_cast<const int&>(17);
+ // CHECK: store i32 17, i32*
+ return 17;
+}
+
+// CHECK-LABEL: define dereferenceable({{[0-9]+}}) i16* @_Z20lvalue_integral_castv()
+const short &lvalue_integral_cast() {
+ if (i == 0)
+ // CHECK: store i16 17, i16*
+ return (const short&)17;
+ else if (i == 1)
+ // CHECK: store i16 17, i16*
+ return static_cast<const short&>(17);
+ // CHECK: store i16 17, i16*
+ return 17;
+}
+
+// CHECK-LABEL: define dereferenceable({{[0-9]+}}) i16* @_Z29lvalue_floating_integral_castv()
+const short &lvalue_floating_integral_cast() {
+ if (i == 0)
+ // CHECK: store i16 17, i16*
+ return (const short&)17.5;
+ else if (i == 1)
+ // CHECK: store i16 17, i16*
+ return static_cast<const short&>(17.5);
+ // CHECK: store i16 17, i16*
+ return 17.5;
+}
+
+// CHECK-LABEL: define dereferenceable({{[0-9]+}}) float* @_Z29lvalue_integral_floating_castv()
+const float &lvalue_integral_floating_cast() {
+ if (i == 0)
+ // CHECK: store float 1.700000e+{{0*}}1, float*
+ return (const float&)17;
+ else if (i == 1)
+ // CHECK: store float 1.700000e+{{0*}}1, float*
+ return static_cast<const float&>(17);
+ // CHECK: store float 1.700000e+{{0*}}1, float*
+ return 17;
+}
+
+// CHECK-LABEL: define dereferenceable({{[0-9]+}}) float* @_Z20lvalue_floating_castv()
+const float &lvalue_floating_cast() {
+ if (i == 0)
+ // CHECK: store float 1.700000e+{{0*}}1, float*
+ return (const float&)17.0;
+ else if (i == 1)
+ // CHECK: store float 1.700000e+{{0*}}1, float*
+ return static_cast<const float&>(17.0);
+ // CHECK: store float 1.700000e+{{0*}}1, float*
+ return 17.0;
+}
+
+int get_int();
+
+// CHECK-LABEL: define dereferenceable({{[0-9]+}}) i8* @_Z24lvalue_integer_bool_castv()
+const bool &lvalue_integer_bool_cast() {
+ if (i == 0)
+ // CHECK: call i32 @_Z7get_intv()
+ // CHECK: store i8
+ return (const bool&)get_int();
+ else if (i == 1)
+ // CHECK: call i32 @_Z7get_intv()
+ // CHECK: store i8
+ return static_cast<const bool&>(get_int());
+ // CHECK: call i32 @_Z7get_intv()
+ // CHECK: store i8
+ return get_int();
+}
+
+float get_float();
+
+// CHECK-LABEL: define dereferenceable({{[0-9]+}}) i8* @_Z25lvalue_floating_bool_castv()
+const bool &lvalue_floating_bool_cast() {
+ if (i == 0)
+ // CHECK: call float @_Z9get_floatv()
+ // CHECK: fcmp une float
+ // CHECK: store i8
+ return (const bool&)get_float();
+ else if (i == 1)
+ // CHECK: call float @_Z9get_floatv()
+ // CHECK: fcmp une float
+ // CHECK: store i8
+ return static_cast<const bool&>(get_float());
+ // CHECK: call float @_Z9get_floatv()
+ // CHECK: fcmp une float
+ // CHECK: store i8
+ return get_float();
+}
+
+struct X { };
+typedef int X::*pm;
+typedef int (X::*pmf)(int);
+
+pm get_pointer_to_member_data();
+pmf get_pointer_to_member_function();
+
+// CHECK-LABEL: define dereferenceable({{[0-9]+}}) i8* @_Z26lvalue_ptrmem_to_bool_castv()
+const bool &lvalue_ptrmem_to_bool_cast() {
+ if (i == 0)
+ // CHECK: call i64 @_Z26get_pointer_to_member_datav()
+ // CHECK: store i8
+ // CHECK: store i8*
+ return (const bool&)get_pointer_to_member_data();
+ else if (i == 1)
+ // CHECK: call i64 @_Z26get_pointer_to_member_datav()
+ // CHECK: store i8
+ // CHECK: store i8*
+ return static_cast<const bool&>(get_pointer_to_member_data());
+ // CHECK: call i64 @_Z26get_pointer_to_member_datav()
+ // CHECK: store i8
+ // CHECK: store i8*
+ return get_pointer_to_member_data();
+}
+
+// CHECK-LABEL: define dereferenceable({{[0-9]+}}) i8* @_Z27lvalue_ptrmem_to_bool_cast2v
+const bool &lvalue_ptrmem_to_bool_cast2() {
+ if (i == 0)
+ // CHECK: {{call.*_Z30get_pointer_to_member_functionv}}
+ // CHECK: store i8
+ // CHECK: store i8*
+ return (const bool&)get_pointer_to_member_function();
+ else if (i == 1)
+ // CHECK: {{call.*_Z30get_pointer_to_member_functionv}}
+ // CHECK: store i8
+ // CHECK: store i8*
+ return static_cast<const bool&>(get_pointer_to_member_function());
+ // CHECK: {{call.*_Z30get_pointer_to_member_functionv}}
+ // CHECK: store i8
+ // CHECK: store i8*
+ return get_pointer_to_member_function();
+}
+
+_Complex double get_complex_double();
+
+// CHECK: {{define.*_Z2f1v}}
+const _Complex float &f1() {
+ if (i == 0)
+ // CHECK: {{call.*_Z18get_complex_doublev}}
+ // CHECK: fptrunc
+ // CHECK: fptrunc
+ // CHECK: store float
+ // CHECK: store float
+ return (const _Complex float&)get_complex_double();
+ else if (i == 1)
+ // CHECK: {{call.*_Z18get_complex_doublev}}
+ // CHECK: fptrunc
+ // CHECK: fptrunc
+ // CHECK: store float
+ // CHECK: store float
+ return static_cast<const _Complex float&>(get_complex_double());
+ // CHECK: {{call.*_Z18get_complex_doublev}}
+ // CHECK: fptrunc
+ // CHECK: fptrunc
+ // CHECK: store float
+ // CHECK: store float
+ return get_complex_double();
+}
+
+// CHECK-LABEL: define i32 @_Z7pr10592RKi(i32*
+unsigned pr10592(const int &v) {
+ // CHECK: [[VADDR:%[a-zA-Z0-9.]+]] = alloca i32*
+ // CHECK-NEXT: [[REFTMP:%[a-zA-Z0-9.]+]] = alloca i32
+ // CHECK-NEXT: store i32* [[V:%[a-zA-Z0-9.]+]], i32** [[VADDR]]
+ // CHECK-NEXT: [[VADDR_1:%[a-zA-Z0-9.]+]] = load i32*, i32** [[VADDR]]
+ // CHECK-NEXT: [[VVAL:%[a-zA-Z0-9.]+]] = load i32, i32* [[VADDR_1]]
+ // CHECK-NEXT: store i32 [[VVAL]], i32* [[REFTMP]]
+ // CHECK-NEXT: [[VVAL_I:%[a-zA-Z0-9.]+]] = load i32, i32* [[REFTMP]]
+ // CHECK-NEXT: ret i32 [[VVAL_I]]
+ return static_cast<const unsigned &>(v);
+}
+
+namespace PR10650 {
+ struct Helper {
+ unsigned long long id();
+ };
+ unsigned long long test(Helper *obj) {
+ return static_cast<const unsigned long long&>(obj->id());
+ }
+ // CHECK-LABEL: define i64 @_ZN7PR106504testEPNS_6HelperE
+ // CHECK: store i64
+}
+
+// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/reference-field.cpp b/src/llvm-project/clang/test/CodeGenCXX/reference-field.cpp
new file mode 100644
index 0000000..54e914d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/reference-field.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -o - %s -O2 | FileCheck %s
+
+// Make sure the call to b() doesn't get optimized out.
+extern struct x {char& x,y;}y;
+int b();
+int a() { if (!&y.x) b(); }
+
+// CHECK: @_Z1bv
diff --git a/src/llvm-project/clang/test/CodeGenCXX/reference-in-block-args.cpp b/src/llvm-project/clang/test/CodeGenCXX/reference-in-block-args.cpp
new file mode 100644
index 0000000..1ff1ae2
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/reference-in-block-args.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -fblocks %s -emit-llvm -o %t
+// rdar: // 8041962
+
+extern "C" int printf(const char*, ...);
+
+struct ST {
+ int filler;
+ int referrer;
+};
+
+void OUTER_BLOCK(void (^fixer)(ST& ref)) {
+ ST ref = {2, 100};
+ fixer(ref);
+}
+
+void INNER_BLOCK(int (^largeDo) ()) {
+ printf("%d\n", largeDo());
+}
+
+void scan() {
+ OUTER_BLOCK(^(ST &ref) {
+ INNER_BLOCK(^() { return ref.referrer + ref.filler; });
+ });
+
+}
+
+int main() {
+ scan();
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/reference-in-blocks.cpp b/src/llvm-project/clang/test/CodeGenCXX/reference-in-blocks.cpp
new file mode 100644
index 0000000..388ec7c
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/reference-in-blocks.cpp
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -fblocks %s -emit-llvm -o %t
+
+extern "C" int printf(const char*, ...);
+
+template<typename T> class range {
+public:
+T _i;
+ range(T i) {_i = i;};
+ T get() {return _i;};
+};
+
+// rdar: // 7495203
+class A {
+ public:
+ A() : field(10), d1(3.14) {}
+ void F();
+ void S() {
+ printf(" field = %d\n", field);
+ printf(" field = %f\n", d1);
+ }
+ int field;
+ double d1;
+};
+
+void A::F()
+ {
+ __block A &tlc = *this;
+ // crashed in code gen (radar 7495203)
+ ^{ tlc.S(); }();
+ }
+
+int main() {
+
+ // works
+ void (^bl)(range<int> ) = ^(range<int> i){printf("Hello Blocks %d\n", i.get()); };
+
+ //crashes in godegen?
+ void (^bl2)(range<int>& ) = ^(range<int>& i){printf("Hello Blocks %d\n", i.get()); };
+
+ A *a = new A;
+ a->F();
+ return 0;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/reference-init.cpp b/src/llvm-project/clang/test/CodeGenCXX/reference-init.cpp
new file mode 100644
index 0000000..5a91d3b
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/reference-init.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -verify %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm %s -o - -std=c++98 | FileCheck %s --check-prefix=CHECK-CXX98
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm %s -o - -std=c++11 | FileCheck %s --check-prefix=CHECK-CXX11
+// expected-no-diagnostics
+
+#if __cplusplus >= 201103L
+// CHECK-CXX11: @_ZZ15InitRefWithListvE1r = internal constant i32* @_ZGRZ15InitRefWithListvE1r_
+// CHECK-CXX11: @_ZGRZ15InitRefWithListvE1r_ = internal constant i32 123
+int InitRefWithList() { static const int &r = {123}; return r; }
+#endif
+
+struct XPTParamDescriptor {};
+struct nsXPTParamInfo {
+ nsXPTParamInfo(const XPTParamDescriptor& desc);
+};
+void a(XPTParamDescriptor *params) {
+ const nsXPTParamInfo& paramInfo = params[0];
+}
+
+// CodeGen of reference initialized const arrays.
+namespace PR5911 {
+ template <typename T, int N> int f(const T (&a)[N]) { return N; }
+ int iarr[] = { 1 };
+ int test() { return f(iarr); }
+}
+
+// radar 7574896
+struct Foo { int foo; };
+Foo& ignoreSetMutex = *(new Foo);
+
+// Binding to a bit-field that requires a temporary.
+struct { int bitfield : 3; } s = { 3 };
+const int &s2 = s.bitfield;
+
+// In C++98, this forms a reference to itself. In C++11 onwards, this performs
+// copy-construction.
+struct SelfReference { SelfReference &r; };
+extern SelfReference self_reference_1;
+SelfReference self_reference_2 = {self_reference_1};
+// CHECK-CXX98: @self_reference_2 = {{.*}}global %[[SELF_REF:.*]] { %[[SELF_REF]]* @self_reference_1 }
+// CHECK-CXX11: @self_reference_2 = {{(dso_local )?}}global %[[SELF_REF:.*]] zeroinitializer
+// CHECK-CXX11: call {{.*}}memcpy{{.*}} @self_reference_2 {{.*}} @self_reference_1
diff --git a/src/llvm-project/clang/test/CodeGenCXX/references.cpp b/src/llvm-project/clang/test/CodeGenCXX/references.cpp
new file mode 100644
index 0000000..180e0cf
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/references.cpp
@@ -0,0 +1,312 @@
+// RUN: not %clang_cc1 -triple x86_64-apple-darwin -verify -emit-llvm -o - %s | FileCheck %s
+void t1() {
+ // CHECK-LABEL: define void @_Z2t1v
+ // CHECK: [[REFLOAD:%.*]] = load i32*, i32** @a, align 8
+ // CHECK: load i32, i32* [[REFLOAD]], align 4
+ extern int& a;
+ int b = a;
+}
+
+void t2(int& a) {
+ // CHECK-LABEL: define void @_Z2t2Ri
+ // CHECK: [[REFLOAD2:%.*]] = load i32*, i32** {{.*}}, align 8
+ // CHECK: load i32, i32* [[REFLOAD2]], align 4
+ int b = a;
+}
+
+int g;
+int& gr = g;
+int& grr = gr;
+void t3() {
+ int b = gr;
+}
+
+// Test reference binding.
+
+struct C { int a; };
+void f(const bool&);
+void f(const int&);
+void f(const _Complex int&);
+void f(const C&);
+
+C aggregate_return();
+
+bool& bool_reference_return();
+int& int_reference_return();
+_Complex int& complex_int_reference_return();
+C& aggregate_reference_return();
+
+void test_bool() {
+ bool a = true;
+ f(a);
+
+ f(true);
+
+ bool_reference_return() = true;
+ a = bool_reference_return();
+
+ struct { const bool& b; } b = { true };
+}
+
+void test_scalar() {
+ int a = 10;
+ f(a);
+
+ struct { int bitfield : 3; } s = { 3 };
+ f(s.bitfield);
+
+ f(10);
+
+ __attribute((vector_size(16))) typedef int vec4;
+ f((vec4){1,2,3,4}[0]);
+
+ int_reference_return() = 10;
+ a = int_reference_return();
+
+ struct { const int& a; } agg = { 10 };
+}
+
+void test_complex() {
+ _Complex int a = 10i;
+ f(a);
+
+ f(10i);
+
+ complex_int_reference_return() = 10i;
+ a = complex_int_reference_return();
+
+ struct { const _Complex int &a; } agg = { 10i };
+}
+
+void test_aggregate() {
+ C c;
+ f(c);
+
+ f(aggregate_return());
+ aggregate_reference_return().a = 10;
+
+ c = aggregate_reference_return();
+
+ struct { const C& a; } agg = { C() };
+}
+
+int& reference_return() {
+ return g;
+}
+
+int reference_decl() {
+ int& a = g;
+ const int& b = 1;
+ return a+b;
+}
+
+struct A {
+ int& b();
+};
+
+void f(A* a) {
+ int b = a->b();
+}
+
+// PR5122
+void *foo = 0;
+void * const & kFoo = foo;
+
+struct D : C { D(); ~D(); };
+
+void h() {
+ // CHECK: call void @_ZN1DD1Ev
+ const C& c = D();
+}
+
+namespace T {
+ struct A {
+ A();
+ ~A();
+ };
+
+ struct B {
+ B();
+ ~B();
+ A f();
+ };
+
+ void f() {
+ // CHECK: call void @_ZN1T1BC1Ev
+ // CHECK: call void @_ZN1T1B1fEv
+ // CHECK: call void @_ZN1T1BD1Ev
+ const A& a = B().f();
+ // CHECK: call void @_ZN1T1fEv
+ f();
+ // CHECK: call void @_ZN1T1AD1Ev
+ }
+}
+
+// PR5227.
+namespace PR5227 {
+void f(int &a) {
+ (a = 10) = 20;
+}
+}
+
+// PR5590
+struct s0;
+struct s1 { struct s0 &s0; };
+void f0(s1 a) { s1 b = a; }
+
+// PR6024
+// CHECK: @_Z2f2v()
+// CHECK: alloca i32,
+// CHECK-NEXT: store
+// CHECK-NEXT: ret
+const int &f2() { return 0; }
+
+// Don't constant fold const reference parameters with default arguments to
+// their default arguments.
+namespace N1 {
+ const int foo = 1;
+ // CHECK: @_ZN2N14test
+ void test(const int& arg = foo) {
+ // Ensure this array is on the stack where we can set values instead of
+ // being a global constant.
+ // CHECK: %args_array = alloca
+ const int* const args_array[] = { &arg };
+ }
+}
+
+// Bind to subobjects while extending the life of the complete object.
+namespace N2 {
+ class X {
+ public:
+ X(const X&);
+ X &operator=(const X&);
+ ~X();
+ };
+
+ struct P {
+ X first;
+ };
+
+ P getP();
+
+ // CHECK-LABEL: define void @_ZN2N21fEi
+ // CHECK: call void @_ZN2N24getPEv
+ // CHECK: getelementptr inbounds
+ // CHECK: store i32 17
+ // CHECK: call void @_ZN2N21PD1Ev
+ void f(int i) {
+ const X& xr = getP().first;
+ i = 17;
+ }
+
+ struct SpaceWaster {
+ int i, j;
+ };
+
+ struct ReallyHasX {
+ X x;
+ };
+
+ struct HasX : ReallyHasX { };
+
+ struct HasXContainer {
+ HasX has;
+ };
+
+ struct Y : SpaceWaster, HasXContainer { };
+ struct Z : SpaceWaster, Y { };
+
+ Z getZ();
+
+ // CHECK-LABEL: define void @_ZN2N21gEi
+ // CHECK: call void @_ZN2N24getZEv
+ // CHECK: {{getelementptr inbounds.*i32 0, i32 0}}
+ // CHECK: {{getelementptr inbounds.*i32 0, i32 0}}
+ // CHECK: store i32 19
+ // CHECK: call void @_ZN2N21ZD1Ev
+ // CHECK: ret void
+ void g(int i) {
+ const X &xr = getZ().has.x;
+ i = 19;
+ }
+}
+
+namespace N3 {
+
+// PR7326
+
+struct A {
+ explicit A(int);
+ ~A();
+};
+
+// CHECK-LABEL: define internal void @__cxx_global_var_init
+// CHECK: call void @_ZN2N31AC1Ei(%"struct.N3::A"* @_ZGRN2N35sA123E_, i32 123)
+// CHECK: call i32 @__cxa_atexit
+// CHECK: ret void
+const A &sA123 = A(123);
+}
+
+namespace N4 {
+
+struct A {
+ A();
+ ~A();
+};
+
+void f() {
+ // CHECK-LABEL: define void @_ZN2N41fEv
+ // CHECK: call void @_ZN2N41AC1Ev(%"struct.N4::A"* @_ZGRZN2N41fEvE2ar_)
+ // CHECK: call i32 @__cxa_atexit
+ // CHECK: ret void
+ static const A& ar = A();
+
+}
+}
+
+// PR9494
+namespace N5 {
+struct AnyS { bool b; };
+void f(const bool&);
+AnyS g();
+void h() {
+ // CHECK: call i8 @_ZN2N51gEv()
+ // CHECK: call void @_ZN2N51fERKb(i8*
+ f(g().b);
+}
+}
+
+// PR9565
+namespace PR9565 {
+ struct a { int a : 10, b : 10; };
+ // CHECK-LABEL: define void @_ZN6PR95651fEv()
+ void f() {
+ // CHECK: call void @llvm.memcpy
+ a x = { 0, 0 };
+ // CHECK: [[WITH_SEVENTEEN:%[.a-zA-Z0-9]+]] = or i32 [[WITHOUT_SEVENTEEN:%[.a-zA-Z0-9]+]], 17
+ // CHECK: store i32 [[WITH_SEVENTEEN]], i32* [[XA:%[.a-zA-Z0-9]+]]
+ x.a = 17;
+ // CHECK-NEXT: bitcast
+ // CHECK-NEXT: load
+ // CHECK-NEXT: shl
+ // CHECK-NEXT: ashr
+ // CHECK-NEXT: store i32
+ // CHECK-NEXT: store i32*
+ const int &y = x.a;
+ // CHECK-NEXT: bitcast
+ // CHECK-NEXT: load
+ // CHECK-NEXT: and
+ // CHECK-NEXT: or i32 {{.*}}, 19456
+ // CHECK-NEXT: store i32
+ x.b = 19;
+ // CHECK-NEXT: ret void
+ }
+}
+
+namespace N6 {
+ extern struct x {char& x;}y;
+ int a() { return y.x; }
+ // CHECK-LABEL: define i32 @_ZN2N61aEv
+ // CHECK: [[REFLOAD3:%.*]] = load i8*, i8** getelementptr inbounds (%"struct.N6::x", %"struct.N6::x"* @_ZN2N61yE, i32 0, i32 0), align 8
+ // CHECK: load i8, i8* [[REFLOAD3]], align 1
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/regcall.cpp b/src/llvm-project/clang/test/CodeGenCXX/regcall.cpp
new file mode 100644
index 0000000..fbc1dbf
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/regcall.cpp
@@ -0,0 +1,105 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -std=c++11 %s -o - | FileCheck -allow-deprecated-dag-overlap -check-prefix=CHECK-LIN -check-prefix=CHECK-LIN64 %s
+// RUN: %clang_cc1 -triple i386-linux-gnu -emit-llvm -std=c++11 %s -o - | FileCheck -allow-deprecated-dag-overlap -check-prefix=CHECK-LIN -check-prefix=CHECK-LIN32 %s
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c++11 %s -o - -DWIN_TEST | FileCheck -allow-deprecated-dag-overlap -check-prefix=CHECK-WIN64 %s
+// RUN: %clang_cc1 -triple i386-windows-msvc -emit-llvm -std=c++11 %s -o - -DWIN_TEST | FileCheck -allow-deprecated-dag-overlap -check-prefix=CHECK-WIN32 %s
+
+int __regcall foo(int i);
+
+int main()
+{
+ int p = 0, _data;
+ auto lambda = [&](int parameter) -> int {
+ _data = foo(parameter);
+ return _data;
+ };
+ return lambda(p);
+}
+// CHECK-LIN: call x86_regcallcc {{.+}} @_Z15__regcall3__foo
+// CHECK-WIN64: call x86_regcallcc {{.+}} @"?foo@@YwHH@Z"
+// CHECK-WIN32: call x86_regcallcc {{.+}} @"?foo@@YwHH@Z"
+
+int __regcall foo (int i){
+ return i;
+}
+// CHECK-LIN: define x86_regcallcc {{.+}}@_Z15__regcall3__foo
+// CHECK-WIN64: define dso_local x86_regcallcc {{.+}}@"?foo@@YwHH@Z"
+// CHECK-WIN32: define dso_local x86_regcallcc {{.+}}@"?foo@@YwHH@Z"
+
+// used to give a body to test_class functions
+static int x = 0;
+class test_class {
+ int a;
+public:
+#ifndef WIN_TEST
+ __regcall
+#endif
+ test_class(){++x;}
+ // CHECK-LIN-DAG: define linkonce_odr x86_regcallcc void @_ZN10test_classC1Ev
+ // CHECK-LIN-DAG: define linkonce_odr x86_regcallcc void @_ZN10test_classC2Ev
+ // Windows ignores calling convention on constructor/destructors.
+ // CHECK-WIN64-DAG: define linkonce_odr dso_local %class.test_class* @"??0test_class@@QEAA@XZ"
+ // CHECK-WIN32-DAG: define linkonce_odr dso_local x86_thiscallcc %class.test_class* @"??0test_class@@QAE@XZ"
+
+#ifndef WIN_TEST
+ __regcall
+#endif
+ ~test_class(){--x;}
+ // CHECK-LIN-DAG: define linkonce_odr x86_regcallcc void @_ZN10test_classD2Ev
+ // CHECK-LIN-DAG: define linkonce_odr x86_regcallcc void @_ZN10test_classD1Ev
+ // Windows ignores calling convention on constructor/destructors.
+ // CHECK-WIN64-DAG: define linkonce_odr dso_local void @"??1test_class@@QEAA@XZ"
+ // CHECK-WIN32-DAG: define linkonce_odr dso_local x86_thiscallcc void @"??1test_class@@QAE@XZ"
+
+ test_class& __regcall operator+=(const test_class&){
+ return *this;
+ }
+ // CHECK-LIN-DAG: define linkonce_odr x86_regcallcc dereferenceable(4) %class.test_class* @_ZN10test_classpLERKS_
+ // CHECK-WIN64-DAG: define linkonce_odr dso_local x86_regcallcc dereferenceable(4) %class.test_class* @"??Ytest_class@@QEAwAEAV0@AEBV0@@Z"
+ // CHECK-WIN32-DAG: define linkonce_odr dso_local x86_regcallcc dereferenceable(4) %class.test_class* @"??Ytest_class@@QAwAAV0@ABV0@@Z"
+ void __regcall do_thing(){}
+ // CHECK-LIN-DAG: define linkonce_odr x86_regcallcc void @_ZN10test_class20__regcall3__do_thingEv
+ // CHECK-WIN64-DAG: define linkonce_odr dso_local x86_regcallcc void @"?do_thing@test_class@@QEAwXXZ"
+ // CHECK-WIN32-DAG: define linkonce_odr dso_local x86_regcallcc void @"?do_thing@test_class@@QAwXXZ"
+
+ template<typename T>
+ void __regcall tempFunc(T i){}
+ // CHECK-LIN-DAG: define linkonce_odr x86_regcallcc void @_ZN10test_class20__regcall3__tempFuncIiEEvT_
+ // CHECK-WIN64-DAG: define linkonce_odr dso_local x86_regcallcc void @"??$freeTempFunc@H@@YwXH@Z"
+ // CHECK-WIN32-DAG: define linkonce_odr dso_local x86_regcallcc void @"??$freeTempFunc@H@@YwXH@Z"
+};
+
+bool __regcall operator ==(const test_class&, const test_class&){ --x; return false;}
+// CHECK-LIN-DAG: define x86_regcallcc zeroext i1 @_ZeqRK10test_classS1_
+// CHECK-WIN64-DAG: define dso_local x86_regcallcc zeroext i1 @"??8@Yw_NAEBVtest_class@@0@Z"
+// CHECK-WIN32-DAG: define dso_local x86_regcallcc zeroext i1 @"??8@Yw_NABVtest_class@@0@Z"
+
+test_class __regcall operator""_test_class (unsigned long long) { ++x; return test_class{};}
+// CHECK-LIN64-DAG: define x86_regcallcc void @_Zli11_test_classy(%class.test_class* noalias sret %agg.result, i64)
+// CHECK-LIN32-DAG: define x86_regcallcc void @_Zli11_test_classy(%class.test_class* inreg noalias sret %agg.result, i64)
+// CHECK-WIN64-DAG: ??__K_test_class@@Yw?AVtest_class@@_K@Z"
+// CHECK-WIN32-DAG: ??__K_test_class@@Yw?AVtest_class@@_K@Z"
+
+template<typename T>
+void __regcall freeTempFunc(T i){}
+// CHECK-LIN-DAG: define linkonce_odr x86_regcallcc void @_Z24__regcall3__freeTempFuncIiEvT_
+// CHECK-WIN64-DAG: define linkonce_odr dso_local x86_regcallcc void @"??$freeTempFunc@H@@YwXH@Z"
+// CHECK-WIN32-DAG: define linkonce_odr dso_local x86_regcallcc void @"??$freeTempFunc@H@@YwXH@Z"
+
+// class to force generation of functions
+void force_gen() {
+ test_class t;
+ test_class t2 = 12_test_class;
+ t += t2;
+ auto t3 = 100_test_class;
+ t3.tempFunc(1);
+ freeTempFunc(1);
+ t3.do_thing();
+}
+
+long double _Complex __regcall foo(long double _Complex f) {
+ return f;
+}
+// CHECK-LIN64-DAG: define x86_regcallcc void @_Z15__regcall3__fooCe({ x86_fp80, x86_fp80 }* noalias sret %agg.result, { x86_fp80, x86_fp80 }* byval align 16 %f)
+// CHECK-LIN32-DAG: define x86_regcallcc void @_Z15__regcall3__fooCe({ x86_fp80, x86_fp80 }* inreg noalias sret %agg.result, { x86_fp80, x86_fp80 }* byval align 4 %f)
+// CHECK-WIN64-DAG: define dso_local x86_regcallcc { double, double } @"?foo@@YwU?$_Complex@O@__clang@@U12@@Z"(double %f.0, double %f.1)
+// CHECK-WIN32-DAG: define dso_local x86_regcallcc { double, double } @"?foo@@YwU?$_Complex@O@__clang@@U12@@Z"(double %f.0, double %f.1)
diff --git a/src/llvm-project/clang/test/CodeGenCXX/regparm.cpp b/src/llvm-project/clang/test/CodeGenCXX/regparm.cpp
new file mode 100644
index 0000000..2196c79
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/regparm.cpp
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o - | FileCheck %s
+
+
+// CHECK: _Z3fooRi(i32* inreg
+void __attribute__ ((regparm (1))) foo(int &a) {
+}
+
+struct S1 {
+ int x;
+ S1(const S1 &y);
+};
+
+void __attribute__((regparm(3))) foo2(S1 a, int b);
+// CHECK: declare void @_Z4foo22S1i(%struct.S1* inreg, i32 inreg)
+void bar2(S1 a, int b) {
+ foo2(a, b);
+}
+
+struct S2 {
+ int x;
+};
+
+void __attribute__((regparm(3))) foo3(struct S2 a, int b);
+// CHECK: declare void @_Z4foo32S2i(i32 inreg, i32 inreg)
+void bar3(struct S2 a, int b) {
+ foo3(a, b);
+}
+
+struct S3 {
+ struct {
+ struct {} b[0];
+ } a;
+};
+__attribute((regparm(2))) void foo4(S3 a, int b);
+// CHECK: declare void @_Z4foo42S3i(%struct.S3* byval align 4, i32 inreg)
+void bar3(S3 a, int b) {
+ foo4(a, b);
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/reinterpret-cast.cpp b/src/llvm-project/clang/test/CodeGenCXX/reinterpret-cast.cpp
new file mode 100644
index 0000000..63c5a2a
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/reinterpret-cast.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s -std=c++11
+// REQUIRES: LP64
+
+void *f1(unsigned long l) {
+ return reinterpret_cast<void *>(l);
+}
+
+unsigned long f2() {
+ return reinterpret_cast<unsigned long>(nullptr);
+}
+
+unsigned long f3(void *p) {
+ return reinterpret_cast<unsigned long>(p);
+}
+
+void f4(int*&);
+void f5(void*& u) {
+ f4(reinterpret_cast<int*&>(u));
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/return.cpp b/src/llvm-project/clang/test/CodeGenCXX/return.cpp
new file mode 100644
index 0000000..584c292
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/return.cpp
@@ -0,0 +1,103 @@
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -std=c++11 -o - %s | FileCheck --check-prefixes=CHECK,CHECK-COMMON %s
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -std=c++11 -O -o - %s | FileCheck %s --check-prefixes=CHECK-OPT,CHECK-COMMON
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -std=c++11 -fno-strict-return -o - %s | FileCheck %s --check-prefixes=CHECK-NOSTRICT,CHECK-COMMON
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -std=c++11 -fno-strict-return -Wno-return-type -o - %s | FileCheck %s --check-prefixes=CHECK-NOSTRICT,CHECK-COMMON
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -std=c++11 -fno-strict-return -O -o - %s | FileCheck %s --check-prefixes=CHECK-NOSTRICT-OPT,CHECK-COMMON
+
+// CHECK-COMMON-LABEL: @_Z9no_return
+int no_return() {
+ // CHECK: call void @llvm.trap
+ // CHECK-NEXT: unreachable
+
+ // CHECK-OPT-NOT: call void @llvm.trap
+ // CHECK-OPT: unreachable
+
+ // -fno-strict-return should not emit trap + unreachable but it should return
+ // an undefined value instead.
+
+ // CHECK-NOSTRICT: alloca
+ // CHECK-NOSTRICT-NEXT: load
+ // CHECK-NOSTRICT-NEXT: ret i32
+ // CHECK-NOSTRICT-NEXT: }
+
+ // CHECK-NOSTRICT-OPT: ret i32 undef
+}
+
+enum Enum {
+ A, B
+};
+
+// CHECK-COMMON-LABEL: @_Z27returnNotViableDontOptimize4Enum
+int returnNotViableDontOptimize(Enum e) {
+ switch (e) {
+ case A: return 1;
+ case B: return 2;
+ }
+ // Undefined behaviour optimization shouldn't be used when -fno-strict-return
+ // is turned on, even if all the enum cases are covered in this function.
+
+ // CHECK-NOSTRICT-NOT: call void @llvm.trap
+ // CHECK-NOSTRICT-NOT: unreachable
+}
+
+struct Trivial {
+ int x;
+};
+
+// CHECK-NOSTRICT-LABEL: @_Z7trivialv
+Trivial trivial() {
+ // This function returns a trivial record so -fno-strict-return should avoid
+ // the undefined behaviour optimization.
+
+ // CHECK-NOSTRICT-NOT: call void @llvm.trap
+ // CHECK-NOSTRICT-NOT: unreachable
+}
+
+struct NonTrivialCopy {
+ NonTrivialCopy(const NonTrivialCopy &);
+};
+
+// CHECK-NOSTRICT-LABEL: @_Z14nonTrivialCopyv
+NonTrivialCopy nonTrivialCopy() {
+ // CHECK-NOSTRICT-NOT: call void @llvm.trap
+ // CHECK-NOSTRICT-NOT: unreachable
+}
+
+struct NonTrivialDefaultConstructor {
+ int x;
+
+ NonTrivialDefaultConstructor() { }
+};
+
+// CHECK-NOSTRICT-LABEL: @_Z28nonTrivialDefaultConstructorv
+NonTrivialDefaultConstructor nonTrivialDefaultConstructor() {
+ // CHECK-NOSTRICT-NOT: call void @llvm.trap
+ // CHECK-NOSTRICT-NOT: unreachable
+}
+
+// Functions that return records with non-trivial destructors should always use
+// the -fstrict-return optimization.
+
+struct NonTrivialDestructor {
+ ~NonTrivialDestructor();
+};
+
+// CHECK-NOSTRICT-LABEL: @_Z20nonTrivialDestructorv
+NonTrivialDestructor nonTrivialDestructor() {
+ // CHECK-NOSTRICT: call void @llvm.trap
+ // CHECK-NOSTRICT-NEXT: unreachable
+}
+
+// The behavior for lambdas should be identical to functions.
+// CHECK-COMMON-LABEL: @_Z10lambdaTestv
+void lambdaTest() {
+ auto lambda1 = []() -> int {
+ };
+ lambda1();
+
+ // CHECK: call void @llvm.trap
+ // CHECK-NEXT: unreachable
+
+ // CHECK-NOSTRICT-NOT: call void @llvm.trap
+ // CHECK-NOSTRICT-NOT: unreachable
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/rtti-fundamental.cpp b/src/llvm-project/clang/test/CodeGenCXX/rtti-fundamental.cpp
new file mode 100644
index 0000000..d0e5890
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/rtti-fundamental.cpp
@@ -0,0 +1,200 @@
+// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -emit-llvm -fvisibility hidden -o - | FileCheck %s -check-prefix=CHECK-HIDDEN
+
+#include <typeinfo>
+
+std::type_info foo() {
+ return typeid(void);
+}
+
+namespace __cxxabiv1 {
+ struct __fundamental_type_info {
+ virtual ~__fundamental_type_info();
+ };
+
+ __fundamental_type_info::~__fundamental_type_info() { }
+}
+
+// void
+// CHECK: @_ZTIv = constant
+// CHECK-HIDDEN: @_ZTIv = hidden constant
+// CHECK: @_ZTIPv = constant
+// CHECK-HIDDEN: @_ZTIPv = hidden constant
+// CHECK: @_ZTIPKv = constant
+// CHECK-HIDDEN: @_ZTIPKv = hidden constant
+
+// std::nullptr_t
+// CHECK: @_ZTIDn = constant
+// CHECK-HIDDEN: @_ZTIDn = hidden constant
+// CHECK: @_ZTIPDn = constant
+// CHECK-HIDDEN: @_ZTIPDn = hidden constant
+// CHECK: @_ZTIPKDn = constant
+// CHECK-HIDDEN: @_ZTIPKDn = hidden constant
+
+// bool
+// CHECK: @_ZTIb = constant
+// CHECK-HIDDEN: @_ZTIb = hidden constant
+// CHECK: @_ZTIPb = constant
+// CHECK-HIDDEN: @_ZTIPb = hidden constant
+// CHECK: @_ZTIPKb = constant
+// CHECK-HIDDEN: @_ZTIPKb = hidden constant
+
+// wchar_t
+// CHECK: @_ZTIw = constant
+// CHECK-HIDDEN: @_ZTIw = hidden constant
+// CHECK: @_ZTIPw = constant
+// CHECK-HIDDEN: @_ZTIPw = hidden constant
+// CHECK: @_ZTIPKw = constant
+// CHECK-HIDDEN: @_ZTIPKw = hidden constant
+
+// char
+// CHECK: @_ZTIc = constant
+// CHECK-HIDDEN: @_ZTIc = hidden constant
+// CHECK: @_ZTIPc = constant
+// CHECK-HIDDEN: @_ZTIPc = hidden constant
+// CHECK: @_ZTIPKc = constant
+// CHECK-HIDDEN: @_ZTIPKc = hidden constant
+
+// unsigned char
+// CHECK: @_ZTIh = constant
+// CHECK-HIDDEN: @_ZTIh = hidden constant
+// CHECK: @_ZTIPh = constant
+// CHECK-HIDDEN: @_ZTIPh = hidden constant
+// CHECK: @_ZTIPKh = constant
+// CHECK-HIDDEN: @_ZTIPKh = hidden constant
+
+// signed char
+// CHECK: @_ZTIa = constant
+// CHECK-HIDDEN: @_ZTIa = hidden constant
+// CHECK: @_ZTIPa = constant
+// CHECK-HIDDEN: @_ZTIPa = hidden constant
+// CHECK: @_ZTIPKa = constant
+// CHECK-HIDDEN: @_ZTIPKa = hidden constant
+
+// short
+// CHECK: @_ZTIs = constant
+// CHECK-HIDDEN: @_ZTIs = hidden constant
+// CHECK: @_ZTIPs = constant
+// CHECK-HIDDEN: @_ZTIPs = hidden constant
+// CHECK: @_ZTIPKs = constant
+// CHECK-HIDDEN: @_ZTIPKs = hidden constant
+
+// unsigned short
+// CHECK: @_ZTIt = constant
+// CHECK-HIDDEN: @_ZTIt = hidden constant
+// CHECK: @_ZTIPt = constant
+// CHECK-HIDDEN: @_ZTIPt = hidden constant
+// CHECK: @_ZTIPKt = constant
+// CHECK-HIDDEN: @_ZTIPKt = hidden constant
+
+// int
+// CHECK: @_ZTIi = constant
+// CHECK-HIDDEN: @_ZTIi = hidden constant
+// CHECK: @_ZTIPi = constant
+// CHECK-HIDDEN: @_ZTIPi = hidden constant
+// CHECK: @_ZTIPKi = constant
+// CHECK-HIDDEN: @_ZTIPKi = hidden constant
+
+// unsigned int
+// CHECK: @_ZTIj = constant
+// CHECK-HIDDEN: @_ZTIj = hidden constant
+// CHECK: @_ZTIPj = constant
+// CHECK-HIDDEN: @_ZTIPj = hidden constant
+// CHECK: @_ZTIPKj = constant
+// CHECK-HIDDEN: @_ZTIPKj = hidden constant
+
+// long
+// CHECK: @_ZTIl = constant
+// CHECK-HIDDEN: @_ZTIl = hidden constant
+// CHECK: @_ZTIPl = constant
+// CHECK-HIDDEN: @_ZTIPl = hidden constant
+// CHECK: @_ZTIPKl = constant
+// CHECK-HIDDEN: @_ZTIPKl = hidden constant
+
+// unsigned long
+// CHECK: @_ZTIm = constant
+// CHECK-HIDDEN: @_ZTIm = hidden constant
+// CHECK: @_ZTIPm = constant
+// CHECK-HIDDEN: @_ZTIPm = hidden constant
+// CHECK: @_ZTIPKm = constant
+// CHECK-HIDDEN: @_ZTIPKm = hidden constant
+
+// long long
+// CHECK: @_ZTIx = constant
+// CHECK-HIDDEN: @_ZTIx = hidden constant
+// CHECK: @_ZTIPx = constant
+// CHECK-HIDDEN: @_ZTIPx = hidden constant
+// CHECK: @_ZTIPKx = constant
+// CHECK-HIDDEN: @_ZTIPKx = hidden constant
+
+// unsigned long long
+// CHECK: @_ZTIy = constant
+// CHECK-HIDDEN: @_ZTIy = hidden constant
+// CHECK: @_ZTIPy = constant
+// CHECK-HIDDEN: @_ZTIPy = hidden constant
+// CHECK: @_ZTIPKy = constant
+// CHECK-HIDDEN: @_ZTIPKy = hidden constant
+
+// __int128
+// CHECK: @_ZTIn = constant
+// CHECK-HIDDEN: @_ZTIn = hidden constant
+// CHECK: @_ZTIPn = constant
+// CHECK-HIDDEN: @_ZTIPn = hidden constant
+// CHECK: @_ZTIPKn = constant
+// CHECK-HIDDEN: @_ZTIPKn = hidden constant
+
+// unsigned __int128
+// CHECK: @_ZTIo = constant
+// CHECK-HIDDEN: @_ZTIo = hidden constant
+// CHECK: @_ZTIPo = constant
+// CHECK-HIDDEN: @_ZTIPo = hidden constant
+// CHECK: @_ZTIPKo = constant
+// CHECK-HIDDEN: @_ZTIPKo = hidden constant
+
+// half
+// CHECK: @_ZTIDh = constant
+// CHECK-HIDDEN: @_ZTIDh = hidden constant
+// CHECK: @_ZTIPDh = constant
+// CHECK-HIDDEN: @_ZTIPDh = hidden constant
+// CHECK: @_ZTIPKDh = constant
+// CHECK-HIDDEN: @_ZTIPKDh = hidden constant
+
+// float
+// CHECK: @_ZTIf = constant
+// CHECK-HIDDEN: @_ZTIf = hidden constant
+// CHECK: @_ZTIPf = constant
+// CHECK-HIDDEN: @_ZTIPf = hidden constant
+// CHECK: @_ZTIPKf = constant
+// CHECK-HIDDEN: @_ZTIPKf = hidden constant
+
+// double
+// CHECK: @_ZTId = constant
+// CHECK-HIDDEN: @_ZTId = hidden constant
+// CHECK: @_ZTIPd = constant
+// CHECK-HIDDEN: @_ZTIPd = hidden constant
+// CHECK: @_ZTIPKd = constant
+// CHECK-HIDDEN: @_ZTIPKd = hidden constant
+
+// long double
+// CHECK: @_ZTIe = constant
+// CHECK-HIDDEN: @_ZTIe = hidden constant
+// CHECK: @_ZTIPe = constant
+// CHECK-HIDDEN: @_ZTIPe = hidden constant
+// CHECK: @_ZTIPKe = constant
+// CHECK-HIDDEN: @_ZTIPKe = hidden constant
+
+// char16_t
+// CHECK: @_ZTIDs = constant
+// CHECK-HIDDEN: @_ZTIDs = hidden constant
+// CHECK: @_ZTIPDs = constant
+// CHECK-HIDDEN: @_ZTIPDs = hidden constant
+// CHECK: @_ZTIPKDs = constant
+// CHECK-HIDDEN: @_ZTIPKDs = hidden constant
+
+// char32_t
+// CHECK: @_ZTIDi = constant
+// CHECK-HIDDEN: @_ZTIDi = hidden constant
+// CHECK: @_ZTIPDi = constant
+// CHECK-HIDDEN: @_ZTIPDi = hidden constant
+// CHECK: @_ZTIPKDi = constant
+// CHECK-HIDDEN: @_ZTIPKDi = hidden constant
diff --git a/src/llvm-project/clang/test/CodeGenCXX/rtti-hidden.cpp b/src/llvm-project/clang/test/CodeGenCXX/rtti-hidden.cpp
new file mode 100644
index 0000000..3ae487f
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/rtti-hidden.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 %s -triple=x86_64-pc-linux -emit-llvm -o - | FileCheck %s
+
+// Test that this is not hidden.
+// CHECK: @_ZTVN10__cxxabiv120__si_class_type_infoE = external global
+
+class foo {
+ virtual void baz();
+};
+struct __attribute__((__visibility__("hidden"))) bar : public foo {};
+bar zed;
diff --git a/src/llvm-project/clang/test/CodeGenCXX/rtti-layout.cpp b/src/llvm-project/clang/test/CodeGenCXX/rtti-layout.cpp
new file mode 100644
index 0000000..0db2577
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/rtti-layout.cpp
@@ -0,0 +1,205 @@
+// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -emit-llvm -O3 -o - | FileCheck %s
+#include <typeinfo>
+
+// vtables.
+extern "C" {
+ const void *_ZTVN10__cxxabiv123__fundamental_type_infoE;
+ const void *_ZTVN10__cxxabiv117__class_type_infoE;
+ const void *_ZTVN10__cxxabiv120__si_class_type_infoE;
+ const void *_ZTVN10__cxxabiv121__vmi_class_type_infoE;
+ const void *_ZTVN10__cxxabiv119__pointer_type_infoE;
+ const void *_ZTVN10__cxxabiv129__pointer_to_member_type_infoE;
+};
+#define fundamental_type_info_vtable _ZTVN10__cxxabiv123__fundamental_type_infoE
+#define class_type_info_vtable _ZTVN10__cxxabiv117__class_type_infoE
+#define si_class_type_info_vtable _ZTVN10__cxxabiv120__si_class_type_infoE
+#define vmi_class_type_info_vtable _ZTVN10__cxxabiv121__vmi_class_type_infoE
+#define pointer_type_info_vtable _ZTVN10__cxxabiv119__pointer_type_infoE
+#define pointer_to_member_type_info_vtable _ZTVN10__cxxabiv129__pointer_to_member_type_infoE
+
+class __pbase_type_info : public std::type_info {
+public:
+ unsigned int __flags;
+ const std::type_info *__pointee;
+
+ enum __masks {
+ __const_mask = 0x1,
+ __volatile_mask = 0x2,
+ __restrict_mask = 0x4,
+ __incomplete_mask = 0x8,
+ __incomplete_class_mask = 0x10
+ };
+};
+
+class __class_type_info : public std::type_info { };
+
+class __si_class_type_info : public __class_type_info {
+public:
+ const __class_type_info *__base_type;
+};
+
+struct __base_class_type_info {
+public:
+ const __class_type_info *__base_type;
+ long __offset_flags;
+
+ enum __offset_flags_masks {
+ __virtual_mask = 0x1,
+ __public_mask = 0x2,
+ __offset_shift = 8
+ };
+};
+
+class __vmi_class_type_info : public __class_type_info {
+public:
+ unsigned int __flags;
+ unsigned int __base_count;
+ __base_class_type_info __base_info[1];
+
+ enum __flags_masks {
+ __non_diamond_repeat_mask = 0x1,
+ __diamond_shaped_mask = 0x2
+ };
+};
+
+template<typename T> const T& to(const std::type_info &info) {
+return static_cast<const T&>(info);
+}
+struct Incomplete;
+
+struct A { int a; };
+struct Empty { };
+
+struct SI1 : A { };
+struct SI2 : Empty { };
+struct SI3 : Empty { virtual void f() { } };
+
+struct VMI1 : private A { };
+struct VMI2 : virtual A { };
+struct VMI3 : A { virtual void f() { } };
+struct VMI4 : A, Empty { };
+
+struct VMIBase1 { int a; };
+struct VMIBase2 : VMIBase1 { int a; };
+struct VMI5 : VMIBase1, VMIBase2 { int a; };
+
+struct VMIBase3 : virtual VMIBase1 { int a; };
+struct VMI6 : virtual VMIBase1, VMIBase3 { int a; };
+
+struct VMI7 : VMIBase1, VMI5, private VMI6 { };
+
+#define CHECK(x) if (!(x)) return __LINE__
+#define CHECK_VTABLE(type, vtable) CHECK(&vtable##_type_info_vtable + 2 == (((void **)&(typeid(type)))[0]))
+#define CHECK_BASE_INFO_TYPE(type, index, base) CHECK(to<__vmi_class_type_info>(typeid(type)).__base_info[(index)].__base_type == &typeid(base))
+#define CHECK_BASE_INFO_OFFSET_FLAGS(type, index, offset, flags) CHECK(to<__vmi_class_type_info>(typeid(type)).__base_info[(index)].__offset_flags == (((offset) << 8) | (flags)))
+
+struct B {
+ static int const volatile (*a)[10];
+ static int (*b)[10];
+
+ static int const volatile (B::*c)[10];
+ static int (B::*d)[10];
+};
+
+// CHECK-LABEL: define i32 @_Z1fv()
+int f() {
+ // Vectors should be treated as fundamental types.
+ typedef short __v4hi __attribute__ ((__vector_size__ (8)));
+ CHECK_VTABLE(__v4hi, fundamental);
+
+ // A does not have any bases.
+ CHECK_VTABLE(A, class);
+
+ // SI1 has a single public base.
+ CHECK_VTABLE(SI1, si_class);
+ CHECK(to<__si_class_type_info>(typeid(SI1)).__base_type == &typeid(A));
+
+ // SI2 has a single public empty base.
+ CHECK_VTABLE(SI2, si_class);
+ CHECK(to<__si_class_type_info>(typeid(SI2)).__base_type == &typeid(Empty));
+
+ // SI3 has a single public empty base. SI3 is dynamic whereas Empty is not, but since Empty is
+ // an empty class, it will still be at offset zero.
+ CHECK_VTABLE(SI3, si_class);
+ CHECK(to<__si_class_type_info>(typeid(SI3)).__base_type == &typeid(Empty));
+
+ // VMI1 has a single base, but it is private.
+ CHECK_VTABLE(VMI1, vmi_class);
+
+ // VMI2 has a single base, but it is virtual.
+ CHECK_VTABLE(VMI2, vmi_class);
+
+ // VMI3 has a single base, but VMI3 is dynamic whereas A is not, and A is not empty.
+ CHECK_VTABLE(VMI3, vmi_class);
+
+ // VMI4 has two bases.
+ CHECK_VTABLE(VMI4, vmi_class);
+
+ // VMI5 has non-diamond shaped inheritance.
+ CHECK_VTABLE(VMI5, vmi_class);
+ CHECK(to<__vmi_class_type_info>(typeid(VMI5)).__flags == __vmi_class_type_info::__non_diamond_repeat_mask);
+ CHECK(to<__vmi_class_type_info>(typeid(VMI5)).__base_count == 2);
+ CHECK_BASE_INFO_TYPE(VMI5, 0, VMIBase1);
+ CHECK_BASE_INFO_OFFSET_FLAGS(VMI5, 0, 0, __base_class_type_info::__public_mask);
+ CHECK_BASE_INFO_TYPE(VMI5, 1, VMIBase2);
+ CHECK_BASE_INFO_OFFSET_FLAGS(VMI5, 1, 4, __base_class_type_info::__public_mask);
+
+ // VMI6 has diamond shaped inheritance.
+ CHECK_VTABLE(VMI6, vmi_class);
+ CHECK(to<__vmi_class_type_info>(typeid(VMI6)).__flags == __vmi_class_type_info::__diamond_shaped_mask);
+ CHECK(to<__vmi_class_type_info>(typeid(VMI6)).__base_count == 2);
+ CHECK_BASE_INFO_TYPE(VMI6, 0, VMIBase1);
+ CHECK_BASE_INFO_OFFSET_FLAGS(VMI6, 0, -24, __base_class_type_info::__public_mask | __base_class_type_info::__virtual_mask);
+ CHECK_BASE_INFO_TYPE(VMI6, 1, VMIBase3);
+ CHECK_BASE_INFO_OFFSET_FLAGS(VMI6, 1, 0, __base_class_type_info::__public_mask);
+
+ // VMI7 has both non-diamond and diamond shaped inheritance.
+ CHECK_VTABLE(VMI7, vmi_class);
+ CHECK(to<__vmi_class_type_info>(typeid(VMI7)).__flags == (__vmi_class_type_info::__non_diamond_repeat_mask | __vmi_class_type_info::__diamond_shaped_mask));
+ CHECK(to<__vmi_class_type_info>(typeid(VMI7)).__base_count == 3);
+ CHECK_BASE_INFO_TYPE(VMI7, 0, VMIBase1);
+ CHECK_BASE_INFO_OFFSET_FLAGS(VMI7, 0, 16, __base_class_type_info::__public_mask);
+ CHECK_BASE_INFO_TYPE(VMI7, 1, VMI5);
+ CHECK_BASE_INFO_OFFSET_FLAGS(VMI7, 1, 20, __base_class_type_info::__public_mask);
+ CHECK_BASE_INFO_TYPE(VMI7, 2, VMI6);
+ CHECK_BASE_INFO_OFFSET_FLAGS(VMI7, 2, 0, 0);
+
+ // Pointers to incomplete classes.
+ CHECK_VTABLE(Incomplete *, pointer);
+ CHECK(to<__pbase_type_info>(typeid(Incomplete *)).__flags == __pbase_type_info::__incomplete_mask);
+ CHECK(to<__pbase_type_info>(typeid(Incomplete **)).__flags == __pbase_type_info::__incomplete_mask);
+ CHECK(to<__pbase_type_info>(typeid(Incomplete ***)).__flags == __pbase_type_info::__incomplete_mask);
+
+ // Member pointers.
+ CHECK_VTABLE(int Incomplete::*, pointer_to_member);
+ CHECK(to<__pbase_type_info>(typeid(int Incomplete::*)).__flags == __pbase_type_info::__incomplete_class_mask);
+ CHECK(to<__pbase_type_info>(typeid(Incomplete Incomplete::*)).__flags == (__pbase_type_info::__incomplete_class_mask | __pbase_type_info::__incomplete_mask));
+ CHECK(to<__pbase_type_info>(typeid(Incomplete A::*)).__flags == (__pbase_type_info::__incomplete_mask));
+
+ // Check that when stripping qualifiers off the pointee type, we correctly handle arrays.
+ CHECK(to<__pbase_type_info>(typeid(B::a)).__flags == (__pbase_type_info::__const_mask | __pbase_type_info::__volatile_mask));
+ CHECK(to<__pbase_type_info>(typeid(B::a)).__pointee == to<__pbase_type_info>(typeid(B::b)).__pointee);
+ CHECK(to<__pbase_type_info>(typeid(B::c)).__flags == (__pbase_type_info::__const_mask | __pbase_type_info::__volatile_mask));
+ CHECK(to<__pbase_type_info>(typeid(B::c)).__pointee == to<__pbase_type_info>(typeid(B::d)).__pointee);
+
+ // Success!
+ // CHECK: ret i32 0
+ return 0;
+}
+
+#ifdef HARNESS
+extern "C" void printf(const char *, ...);
+
+int main() {
+ int result = f();
+
+ if (result == 0)
+ printf("success!\n");
+ else
+ printf("test on line %d failed!\n", result);
+
+ return result;
+}
+#endif
+
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/rtti-linkage.cpp b/src/llvm-project/clang/test/CodeGenCXX/rtti-linkage.cpp
new file mode 100644
index 0000000..b6b72aa
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/rtti-linkage.cpp
@@ -0,0 +1,181 @@
+// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-BOTH
+// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -fvisibility hidden -emit-llvm -o - | FileCheck -check-prefix=CHECK-WITH-HIDDEN -check-prefix=CHECK-BOTH %s
+
+#include <typeinfo>
+
+// CHECK-BOTH: _ZTSP1C = internal constant
+// CHECK-BOTH: _ZTS1C = internal constant
+// CHECK-BOTH: _ZTI1C = internal constant
+// CHECK-BOTH: _ZTIP1C = internal constant
+// CHECK-BOTH: _ZTSPP1C = internal constant
+// CHECK-BOTH: _ZTIPP1C = internal constant
+// CHECK-BOTH: _ZTSM1Ci = internal constant
+// CHECK-BOTH: _ZTIM1Ci = internal constant
+// CHECK-BOTH: _ZTSPM1Ci = internal constant
+// CHECK-BOTH: _ZTIPM1Ci = internal constant
+// CHECK-BOTH: _ZTSM1CS_ = internal constant
+// CHECK-BOTH: _ZTIM1CS_ = internal constant
+// CHECK-BOTH: _ZTSM1CPS_ = internal constant
+// CHECK-BOTH: _ZTIM1CPS_ = internal constant
+// CHECK-BOTH: _ZTSM1A1C = internal constant
+// CHECK: _ZTS1A = linkonce_odr constant
+// CHECK-WITH-HIDDEN: _ZTS1A = linkonce_odr hidden constant
+// CHECK: _ZTI1A = linkonce_odr constant
+// CHECK-WITH-HIDDEN: _ZTI1A = linkonce_odr hidden constant
+// CHECK-BOTH: _ZTIM1A1C = internal constant
+// CHECK-BOTH: _ZTSM1AP1C = internal constant
+// CHECK-BOTH: _ZTIM1AP1C = internal constant
+
+// 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 constant
+// CHECK-WITH-HIDDEN: @_ZTIPK2T4 = linkonce_odr hidden constant
+// CHECK-WITH-HIDDEN: @_ZTSZ2t5vE1A = internal constant
+// CHECK-WITH-HIDDEN: @_ZTIZ2t5vE1A = internal constant
+// CHECK-WITH-HIDDEN: @_ZTSZ2t6vE1A = linkonce_odr hidden constant
+// CHECK-WITH-HIDDEN: @_ZTIZ2t6vE1A = linkonce_odr hidden constant
+// CHECK-WITH-HIDDEN: @_ZTSPZ2t7vE1A = linkonce_odr hidden constant
+// CHECK-WITH-HIDDEN: @_ZTSZ2t7vE1A = linkonce_odr hidden constant
+// CHECK-WITH-HIDDEN: @_ZTIZ2t7vE1A = linkonce_odr hidden constant
+// CHECK-WITH-HIDDEN: @_ZTIPZ2t7vE1A = linkonce_odr hidden constant
+
+// CHECK: _ZTSN12_GLOBAL__N_11DE = internal constant
+// CHECK: _ZTIN12_GLOBAL__N_11DE = internal constant
+// CHECK: _ZTSPN12_GLOBAL__N_11DE = internal constant
+// CHECK: _ZTIPN12_GLOBAL__N_11DE = internal constant
+// CHECK: _ZTSFN12_GLOBAL__N_11DEvE = internal constant
+// CHECK: _ZTIFN12_GLOBAL__N_11DEvE = internal constant
+// CHECK: _ZTSFvN12_GLOBAL__N_11DEE = internal constant
+// CHECK: _ZTIFvN12_GLOBAL__N_11DEE = internal constant
+// CHECK: _ZTSPFvvE = linkonce_odr constant
+// CHECK: _ZTSFvvE = linkonce_odr constant
+// CHECK: _ZTIFvvE = linkonce_odr constant
+// CHECK: _ZTIPFvvE = linkonce_odr constant
+// CHECK: _ZTSN12_GLOBAL__N_11EE = internal constant
+// CHECK: _ZTIN12_GLOBAL__N_11EE = internal constant
+// CHECK: _ZTSA10_i = linkonce_odr constant
+// CHECK: _ZTIA10_i = linkonce_odr constant
+// CHECK: _ZTI1TILj0EE = linkonce_odr constant
+// CHECK: _ZTI1TILj1EE = weak_odr constant
+// CHECK: _ZTI1TILj2EE = external constant
+// CHECK: _ZTSZ2t5vE1A = internal constant
+// CHECK: _ZTIZ2t5vE1A = internal constant
+// CHECK: _ZTS1B = constant
+// CHECK: _ZTI1B = constant
+// CHECK: _ZTS1F = linkonce_odr constant
+// CHECK: _ZTSZ2t6vE1A = linkonce_odr constant
+// CHECK: _ZTIZ2t6vE1A = linkonce_odr constant
+// CHECK: _ZTSPZ2t7vE1A = linkonce_odr constant
+// CHECK: _ZTSZ2t7vE1A = linkonce_odr constant
+// CHECK: _ZTIZ2t7vE1A = linkonce_odr constant
+// CHECK: _ZTIPZ2t7vE1A = linkonce_odr constant
+
+// 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
+// be emitted in this translation unit and have external linkage.
+struct B : A {
+ virtual void f();
+};
+void B::f() { }
+
+// C is an incomplete class type, so any direct or indirect pointer types should have
+// internal linkage, as should the type info for C itself.
+struct C;
+
+void t1() {
+ (void)typeid(C*);
+ (void)typeid(C**);
+ (void)typeid(int C::*);
+ (void)typeid(int C::**);
+ (void)typeid(C C::*);
+ (void)typeid(C *C::*);
+ (void)typeid(C A::*);
+ (void)typeid(C* A::*);
+}
+
+namespace {
+ // D is inside an anonymous namespace, so all type information related to D should have
+ // internal linkage.
+ struct D { };
+
+ // E is also inside an anonymous namespace.
+ enum E { };
+
+};
+
+// F has a key function defined in the translation unit, but it is inline so the RTTI
+// data should be emitted with linkonce_odr linkage.
+struct F {
+ virtual void f();
+};
+
+inline void F::f() { }
+const D getD();
+
+const std::type_info &t2() {
+ (void)typeid(const D);
+ (void)typeid(D *);
+ (void)typeid(D (*)());
+ (void)typeid(void (*)(D));
+ (void)typeid(void (*)(D&));
+ // The exception specification is not part of the RTTI descriptor, so it should not have
+ // internal linkage.
+ (void)typeid(void (*)() throw (D));
+
+ (void)typeid(E);
+
+ return typeid(getD());
+}
+
+namespace Arrays {
+ struct A {
+ static const int a[10];
+ };
+ const std::type_info &f() {
+ return typeid(A::a);
+ }
+}
+
+template <unsigned N> class T {
+ virtual void anchor() {}
+};
+template class T<1>;
+template <> class T<2> { virtual void anchor(); };
+void t3() {
+ (void) typeid(T<0>);
+ (void) typeid(T<1>);
+ (void) typeid(T<2>);
+}
+
+// rdar://problem/8778973
+struct T4 {};
+void t4(const T4 *ptr) {
+ const void *value = &typeid(ptr);
+}
+
+// rdar://16265084
+void t5() {
+ struct A {};
+ const void *value = &typeid(A);
+}
+
+inline void t6() {
+ struct A {};
+ const void *value = &typeid(A);
+}
+void t6_helper() {
+ t6();
+}
+
+inline void t7() {
+ struct A {};
+ const void *value = &typeid(A*);
+}
+void t7_helper() {
+ t7();
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/rtti-mingw64.cpp b/src/llvm-project/clang/test/CodeGenCXX/rtti-mingw64.cpp
new file mode 100644
index 0000000..628a4d0
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/rtti-mingw64.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -triple x86_64-windows-gnu %s -emit-llvm -o - | FileCheck %s
+struct A { int a; };
+struct B : virtual A { int b; };
+B b;
+class C {
+ virtual ~C();
+};
+C::~C() {}
+
+// CHECK: @_ZTI1C = linkonce_odr dso_local
+// CHECK: @_ZTI1B = linkonce_odr dso_local constant { i8*, i8*, i32, i32, i8*, i64 }
+// CHECK-SAME: i8* bitcast (i8** getelementptr inbounds (i8*, i8** @_ZTVN10__cxxabiv121__vmi_class_type_infoE, i64 2) to i8*),
+// CHECK-SAME: i8* getelementptr inbounds ([3 x i8], [3 x i8]* @_ZTS1B, i32 0, i32 0),
+// CHECK-SAME: i32 0,
+// CHECK-SAME: i32 1,
+// CHECK-SAME: i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*),
+// This i64 is important, it should be an i64, not an i32.
+// CHECK-SAME: i64 -6141 }, comdat
diff --git a/src/llvm-project/clang/test/CodeGenCXX/rtti-qualfn.cpp b/src/llvm-project/clang/test/CodeGenCXX/rtti-qualfn.cpp
new file mode 100644
index 0000000..329cd50
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/rtti-qualfn.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -std=c++1z -I%S %s -triple x86_64-linux-gnu -emit-llvm -o - -fcxx-exceptions | FileCheck %s
+
+#include "typeinfo"
+
+struct A {};
+
+// CHECK-DAG: @_ZTIFvvE = linkonce_odr constant { i8*, i8* } { i8* bitcast (i8** getelementptr inbounds (i8*, i8** @_ZTVN10__cxxabiv120__function_type_infoE, i64 2) to i8*), i8* getelementptr inbounds ([5 x i8], [5 x i8]* @_ZTSFvvE, i32 0, i32 0) }, comdat
+// CHECK-DAG: @_ZTIPDoFvvE = linkonce_odr constant { i8*, i8*, i32, i8* } { i8* bitcast (i8** getelementptr inbounds (i8*, i8** @_ZTVN10__cxxabiv119__pointer_type_infoE, i64 2) to i8*), i8* getelementptr inbounds ([8 x i8], [8 x i8]* @_ZTSPDoFvvE, i32 0, i32 0), i32 64, i8* bitcast ({ i8*, i8* }* @_ZTIFvvE to i8*) }, comdat
+auto &ti_noexcept_ptr = typeid(void (A::*)() noexcept);
+// CHECK-DAG: @_ZTIM1ADoFvvE = linkonce_odr constant { i8*, i8*, i32, i8*, i8* } { i8* bitcast (i8** getelementptr inbounds (i8*, i8** @_ZTVN10__cxxabiv129__pointer_to_member_type_infoE, i64 2) to i8*), i8* getelementptr inbounds ([10 x i8], [10 x i8]* @_ZTSM1ADoFvvE, i32 0, i32 0), i32 64, i8* bitcast ({ i8*, i8* }* @_ZTIFvvE to i8*), i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*) }, comdat
+auto &ti_noexcept_memptr = typeid(void (A::*)() noexcept);
+
+// CHECK-LABEL: define void @_Z1fv(
+__attribute__((noreturn)) void f() noexcept {
+ // CHECK: call void @__cxa_throw({{.*}}@_ZTIPDoFvvE
+ throw f;
+}
+
+// CHECK-LABEL: define void @_Z1gM1ADoFvvE(
+void g(__attribute__((noreturn)) void (A::*p)() noexcept) {
+ // CHECK: call void @__cxa_throw({{.*}}@_ZTIM1ADoFvvE
+ throw p;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/rtti-visibility.cpp b/src/llvm-project/clang/test/CodeGenCXX/rtti-visibility.cpp
new file mode 100644
index 0000000..5945be5
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/rtti-visibility.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -emit-llvm -o %t
+// RUN: FileCheck --check-prefix=CHECK-TEST1 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-TEST2 %s < %t
+
+#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 constant
+ // CHECK-TEST1: @_ZTSPN5Test11AE = linkonce_odr hidden constant
+ // CHECK-TEST1: @_ZTIPN5Test11AE = linkonce_odr hidden 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 constant
+ struct A { };
+ void f() {
+ (void)typeid(A);
+ }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/runtime-dllstorage.cpp b/src/llvm-project/clang/test/CodeGenCXX/runtime-dllstorage.cpp
new file mode 100644
index 0000000..7220fa5
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/runtime-dllstorage.cpp
@@ -0,0 +1,159 @@
+// RUN: %clang_cc1 -triple i686-windows-msvc -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck -allow-deprecated-dag-overlap %s -check-prefix CHECK-MS -check-prefix CHECK-MS-DYNAMIC
+// RUN: %clang_cc1 -triple i686-windows-msvc -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -flto-visibility-public-std -emit-llvm -o - %s | FileCheck -allow-deprecated-dag-overlap %s -check-prefix CHECK-MS -check-prefix CHECK-MS-STATIC
+
+// RUN: %clang_cc1 -triple i686-windows-itanium -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck -allow-deprecated-dag-overlap %s -check-prefix CHECK-IA -check-prefix CHECK-DYNAMIC-IA -check-prefix CHECK-DYNAMIC-NODECL-IA -check-prefix CHECK-DYANMIC-IA-CXA-ATEXIT
+// RUN: %clang_cc1 -triple i686-windows-itanium -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -flto-visibility-public-std -emit-llvm -o - %s | FileCheck -allow-deprecated-dag-overlap %s -check-prefix CHECK-IA -check-prefix CHECK-STATIC-IA -check-prefix CHECK-STATIC-NODECL-IA -check-prefix CHECK-IA-STATIC-CXA-ATEXIT
+// RUN: %clang_cc1 -triple i686-windows-itanium -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -DIMPORT_DECLARATIONS -emit-llvm -o - %s | FileCheck -allow-deprecated-dag-overlap %s -check-prefix CHECK-IA -check-prefix CHECK-DYNAMIC-IA -check-prefix CHECK-DYNAMIC-IMPORT-IA -check-prefix CHECK-DYANMIC-IA-CXA-ATEXIT
+// RUN: %clang_cc1 -triple i686-windows-itanium -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -flto-visibility-public-std -DIMPORT_DECLARATIONS -emit-llvm -o - %s | FileCheck -allow-deprecated-dag-overlap %s -check-prefix CHECK-IA -check-prefix CHECK-STATIC-IA -check-prefix CHECK-STATIC-IMPORT-IA -check-prefix CHECK-IA-STATIC-CXA-ATEXIT
+// RUN: %clang_cc1 -triple i686-windows-itanium -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -DEXPORT_DECLARATIONS -emit-llvm -o - %s | FileCheck -allow-deprecated-dag-overlap %s -check-prefix CHECK-IA -check-prefix CHECK-DYNAMIC-IA -check-prefix CHECK-DYANMIC-IA-CXA-ATEXIT
+// RUN: %clang_cc1 -triple i686-windows-itanium -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -flto-visibility-public-std -DEXPORT_DECLARATIONS -emit-llvm -o - %s | FileCheck -allow-deprecated-dag-overlap %s -check-prefix CHECK-IA -check-prefix CHECK-STATIC-IA -check-prefix CHECK-IA-STATIC-CXA-ATEXIT
+// RUN: %clang_cc1 -triple i686-windows-itanium -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -DDECL -emit-llvm -o - %s | FileCheck -allow-deprecated-dag-overlap %s -check-prefix CHECK-IA -check-prefix CHECK-DYNAMIC-IA -check-prefix CHECK-DYNAMIC-DECL-IA -check-prefix CHECK-DYANMIC-IA-CXA-ATEXIT
+// RUN: %clang_cc1 -triple i686-windows-itanium -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -flto-visibility-public-std -DDECL -emit-llvm -o - %s | FileCheck -allow-deprecated-dag-overlap %s -check-prefix CHECK-IA -check-prefix CHECK-STATIC-IA -check-prefix CHECK-STATIC-DECL-IA -check-prefix CHECK-IA-STATIC-CXA-ATEXIT
+// %clang_cc1 -triple i686-windows-itanium -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -fno-use-cxa-atexit -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-DYNAMIC-IA -check-prefix CHECK-DYNAMIC-IA-ATEXIT
+// %clang_cc1 -triple i686-windows-itanium -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -fno-use-cxa-atexit -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-STATIC-IA -check-prefix CHECK-STATIC-IA-ATEXIT
+
+// RUN: %clang_cc1 -triple i686-windows-gnu -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck -allow-deprecated-dag-overlap %s -check-prefix CHECK-IA -check-prefix CHECK-STATIC-IA
+// RUN: %clang_cc1 -triple i686-windows-gnu -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -flto-visibility-public-std -emit-llvm -o - %s | FileCheck -allow-deprecated-dag-overlap %s -check-prefix CHECK-IA -check-prefix CHECK-STATIC-IA
+// RUN: %clang_cc1 -triple i686-windows-cygnus -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck -allow-deprecated-dag-overlap %s -check-prefix CHECK-IA -check-prefix CHECK-DYNAMIC-IA
+// RUN: %clang_cc1 -triple i686-windows-cygnus -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -flto-visibility-public-std -emit-llvm -o - %s | FileCheck -allow-deprecated-dag-overlap %s -check-prefix CHECK-IA -check-prefix CHECK-STATIC-IA
+
+#if defined(IMPORT_DECLARATIONS)
+namespace __cxxabiv1 {
+extern "C" {
+__declspec(dllimport) void __cxa_guard_acquire(unsigned long long *);
+__declspec(dllimport) unsigned char *__cxa_allocate_exception(unsigned long);
+}
+extern "C" __declspec(dllimport) void __cxa_guard_release(unsigned long long *);
+}
+namespace std {
+__declspec(dllimport) __declspec(noreturn) void terminate();
+}
+#elif defined(EXPORT_DECLARATIONS)
+namespace __cxxabiv1 {
+extern "C" {
+__declspec(dllexport) void __cxa_guard_acquire(unsigned long long *);
+__declspec(dllexport) unsigned char *__cxa_allocate_exception(unsigned long);
+}
+extern "C" void __declspec(dllexport) __cxa_guard_release(unsigned long long *);
+}
+namespace std {
+__declspec(dllexport) __declspec(noreturn) void terminate();
+}
+#elif defined(DECL)
+namespace __cxxabiv1 {
+extern "C" unsigned char *__cxa_allocate_exception(unsigned long);
+}
+namespace std {
+__declspec(noreturn) void terminate();
+}
+#else
+namespace std {
+__declspec(noreturn) void terminate();
+}
+#endif
+
+struct s {
+ s() = default;
+ s(unsigned char) { throw 0; }
+ int m() const;
+};
+
+struct t {
+ ~t();
+ int m() const;
+};
+
+struct u {
+ ~u();
+};
+
+s o;
+thread_local t t;
+u v;
+__declspec(thread) s q;
+
+void __declspec(noinline) f() {
+ throw 0;
+}
+
+void g();
+void __declspec(noinline) h() {
+ try {
+ g();
+ } catch (const int &) {
+ return;
+ } catch (...) {
+ throw;
+ }
+}
+
+void i() {
+ s r(static_cast<unsigned char>('\t'));
+}
+
+int j() {
+ static thread_local struct t v;
+ static struct t *w = new struct t;
+ return w->m() ? v.m() : w->m();
+}
+
+void k() noexcept {
+ g();
+}
+
+void l() {
+ std::terminate();
+}
+
+// CHECK-MS-DAG: @_Init_thread_epoch = external thread_local global i32
+// CHECK-MS-DAG: declare dso_local i32 @__tlregdtor(void ()*)
+// CHECK-MS-DAG: declare dso_local i32 @atexit(void ()*)
+// CHECK-MS-DYNAMIC-DAG: declare dllimport {{.*}} void @_CxxThrowException
+// CHECK-MS-STATIC-DAG: declare {{.*}} void @_CxxThrowException
+// CHECK-MS-DAG: declare dso_local noalias i8* @"??2@YAPAXI@Z"
+// CHECK-MS-DAG: declare dso_local void @_Init_thread_header(i32*)
+// CHECK-MS-DAG: declare dso_local void @_Init_thread_footer(i32*)
+
+// CHECK-IA-DAG: @_ZTH1t = dso_local alias void (), void ()* @__tls_init
+// CHECK-IA-DAG: declare dso_local i32 @__gxx_personality_v0(...)
+// CHECK-IA-DAG: define linkonce_odr hidden void @__clang_call_terminate(i8*)
+
+// CHECK-DYNAMIC-IA-DAG: declare dllimport i32 @__cxa_thread_atexit(void (i8*)*, i8*, i8*)
+// CHECK-DYNAMIC-IA-DAG: declare dllimport i32 @__cxa_atexit(void (i8*)*, i8*, i8*)
+// CHECK-DYNAMIC-IA-DECL-DAG: declare i8* @__cxa_allocate_exception(i32)
+// CHECK-DYNAMIC-IA-NODECL-DAG: declare dllimport i8* @__cxa_allocate_exception(i32)
+// CHECK-DYNAMIC-IA-IMPORT-DAG: declare dllimport i8* @__cxa_allocate_exception(i32)
+// CHECK-DYNAMIC-IA-EXPORT-DAG: declare dllimport i8* @__cxa_allocate_exception(i32)
+// CHECK-DYNAMIC-IA-DAG: declare dllimport void @__cxa_throw(i8*, i8*, i8*)
+// CHECK-DYNAMIC-DECL-IA-DAG: declare dllimport i32 @__cxa_guard_acquire(i64*)
+// CHECK-DYNAMIC-NODECL-IA-DAG: declare dllimport i32 @__cxa_guard_acquire(i64*)
+// CHECK-DYNAMIC-IMPORT-IA-DAG: declare dllimport i32 @__cxa_guard_acquire(i64*)
+// CHECK-DYNAMIC-EXPORT-IA-DAG: declare dllexport i32 @__cxa_guard_acquire(i64*)
+// CHECK-IA-DAG: declare dso_local noalias i8* @_Znwj(i32)
+// CHECK-DYNAMIC-DECL-IA-DAG: declare dllimport void @__cxa_guard_release(i64*)
+// CHECK-DYNAMIC-NODECL-IA-DAG: declare dllimport void @__cxa_guard_release(i64*)
+// CHECK-DYNAMIC-IMPORT-IA-DAG: declare dllimport void @__cxa_guard_release(i64*)
+// CHECK-DYNAMIC-EXPORT-IA-DAG: declare dllimport void @__cxa_guard_release(i64*)
+// CHECK-DYANMIC-IA-DAG: declare dllimport void @_ZSt9terminatev()
+// CHECK-DYNAMIC-NODECL-IA-DAG: declare dso_local void @_ZSt9terminatev()
+// CHECK-DYNAMIC-IMPORT-IA-DAG: declare dllimport void @_ZSt9terminatev()
+// CHECK-DYNAMIC-EXPORT-IA-DAG: declare dso_local dllexport void @_ZSt9terminatev()
+
+// CHECK-STATIC-IA-DAG: declare dso_local i32 @__cxa_thread_atexit(void (i8*)*, i8*, i8*)
+// CHECK-STATIC-IA-DAG: declare dso_local i32 @__cxa_atexit(void (i8*)*, i8*, i8*)
+// CHECK-STATIC-IA-DAG: declare dso_local i8* @__cxa_allocate_exception(i32)
+// CHECK-STATIC-IA-DAG: declare dso_local void @__cxa_throw(i8*, i8*, i8*)
+// CHECK-STATIC-DECL-IA-DAG: declare dso_local i32 @__cxa_guard_acquire(i64*)
+// CHECK-STATIC-NODECL-IA-DAG: declare dso_local i32 @__cxa_guard_acquire(i64*)
+// CHECK-STATIC-IMPORT-IA-DAG: declare dso_local i32 @__cxa_guard_acquire(i64*)
+// CHECK-STATIC-EXPORT-IA-DAG: declare dso_local i32 @__cxa_guard_acquire(i64*)
+// CHECK-IA-DAG: declare dso_local noalias i8* @_Znwj(i32)
+// CHECK-STATIC-DECL-IA-DAG: declare dso_local void @__cxa_guard_release(i64*)
+// CHECK-STATIC-NODECL-IA-DAG: declare dso_local void @__cxa_guard_release(i64*)
+// CHECK-STATIC-IMPORT-IA-DAG: declare dso_local void @__cxa_guard_release(i64*)
+// CHECK-STATIC-EXPORT-IA-DAG: declare dso_local void @__cxa_guard_release(i64*)
+// CHECK-STATIC-IA-DAG: declare dso_local void @_ZSt9terminatev()
+// CHECK-STATIC-NODECL-IA-DAG: declare dso_local void @_ZSt9terminatev()
+// CHECK-STATIC-IMPORT-IA-DAG: declare dso_local void @_ZSt9terminatev()
+// CHECK-STATIC-EXPORT-IA-DAG: declare dso_local dllexport void @_ZSt9terminatev()
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/runtimecc.cpp b/src/llvm-project/clang/test/CodeGenCXX/runtimecc.cpp
new file mode 100644
index 0000000..ad6dc85
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/runtimecc.cpp
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 %s -triple=armv7-apple-darwin10 -emit-llvm -o - -fexceptions -fcxx-exceptions | FileCheck %s
+
+// Check that we annotate all compiler-synthesized runtime calls and
+// functions with the actual ABI-determined CC. This usually doesn't
+// matter as long as we're internally consistent (and the LLVM-default
+// CC is consistent with the real one), but it's possible for user
+// translation units to define these runtime functions (or, equivalently,
+// for us to get LTO'ed with such a translation unit), and then the
+// mismatch will kill us.
+//
+// rdar://12818655
+
+// CHECK: [[A:%.*]] = type { double }
+
+namespace test0 {
+ struct A {
+ double d;
+ A();
+ ~A();
+ };
+
+ A global;
+// CHECK-LABEL: define internal void @__cxx_global_var_init()
+// CHECK: call [[A]]* @_ZN5test01AC1Ev([[A]]* @_ZN5test06globalE)
+// CHECK-NEXT: call i32 @__cxa_atexit(void (i8*)* bitcast ([[A]]* ([[A]]*)* @_ZN5test01AD1Ev to void (i8*)*), i8* bitcast ([[A]]* @_ZN5test06globalE to i8*), i8* @__dso_handle) [[NOUNWIND:#[0-9]+]]
+// CHECK-NEXT: ret void
+}
+
+// CHECK: declare i32 @__cxa_atexit(void (i8*)*, i8*, i8*) [[NOUNWIND]]
+
+namespace test1 {
+ void test() {
+ throw 0;
+ }
+
+// CHECK-LABEL: define void @_ZN5test14testEv()
+// CHECK: [[T0:%.*]] = call i8* @__cxa_allocate_exception(i32 4) [[NOUNWIND]]
+// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to i32*
+// CHECK-NEXT: store i32 0, i32* [[T1]]
+// CHECK-NEXT: call void @__cxa_throw(i8* [[T0]], i8* bitcast (i8** @_ZTIi to i8*), i8* null) [[NORETURN:#[0-9]+]]
+// CHECK-NEXT: unreachable
+}
+
+// CHECK: declare i8* @__cxa_allocate_exception(i32)
+
+// CHECK: declare void @__cxa_throw(i8*, i8*, i8*)
+
+// CHECK-LABEL: define internal void @_GLOBAL__sub_I_runtimecc.cpp()
+// CHECK: call void @__cxx_global_var_init()
+
+
+// CHECK: attributes [[NOUNWIND]] = { nounwind }
+// CHECK: attributes [[NORETURN]] = { noreturn }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/rvalue-references.cpp b/src/llvm-project/clang/test/CodeGenCXX/rvalue-references.cpp
new file mode 100644
index 0000000..47e5745
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/rvalue-references.cpp
@@ -0,0 +1,111 @@
+// RUN: %clang_cc1 -std=c++11 -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-LABEL: define dereferenceable({{[0-9]+}}) %struct.A* @_Z4getAv()
+// CHECK: call dereferenceable({{[0-9]+}}) %struct.B* @_Z4getBv()
+// CHECK-NEXT: bitcast %struct.B*
+// CHECK-NEXT: getelementptr inbounds i8, 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-LABEL: define dereferenceable({{[0-9]+}}) i32* @_Z2f0v()
+// CHECK: call dereferenceable({{[0-9]+}}) i32* @_Z12getIntLValuev()
+// CHECK-NEXT: ret i32*
+int &&f0() { return static_cast<int&&>(getIntLValue()); }
+
+// CHECK-LABEL: define dereferenceable({{[0-9]+}}) i32* @_Z2f1v()
+// CHECK: call dereferenceable({{[0-9]+}}) i32* @_Z12getIntXValuev()
+// CHECK-NEXT: ret i32*
+int &&f1() { return static_cast<int&&>(getIntXValue()); }
+
+// CHECK-LABEL: define dereferenceable({{[0-9]+}}) 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-LABEL: 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-LABEL: 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
+}
+
+// PR10800: don't crash
+namespace test1 {
+ int &&move(int&);
+
+ struct A { A(int); };
+ struct B {
+ A a;
+ B(int i);
+ };
+
+ // CHECK-LABEL: define void @_ZN5test11BC2Ei(
+ // CHECK: [[T0:%.*]] = call dereferenceable({{[0-9]+}}) i32* @_ZN5test14moveERi(
+ // CHECK-NEXT: [[T1:%.*]] = load i32, i32* [[T0]]
+ // CHECK-NEXT: call void @_ZN5test11AC1Ei({{.*}}, i32 [[T1]])
+ // CHECK-NEXT: ret void
+ B::B(int i) : a(move(i)) {}
+}
+
+// PR11009
+struct MoveConvertible {
+ operator int&& () const;
+};
+void moveConstruct() {
+ (void)(int)MoveConvertible();
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/sanitize-dtor-bit-field.cpp b/src/llvm-project/clang/test/CodeGenCXX/sanitize-dtor-bit-field.cpp
new file mode 100644
index 0000000..19c46ba
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/sanitize-dtor-bit-field.cpp
@@ -0,0 +1,84 @@
+// Test -fsanitize-memory-use-after-dtor
+// RUN: %clang_cc1 -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-passes -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-passes -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+// 24 bytes total
+struct Packed {
+ // Packed into 4 bytes
+ unsigned int a : 1;
+ unsigned int b : 1;
+ //unsigned int c : 1;
+ // Force alignment to next 4 bytes
+ unsigned int : 0;
+ unsigned int d : 1;
+ // Force alignment, 8 more bytes
+ double e = 5.0;
+ // 4 bytes
+ unsigned int f : 1;
+ ~Packed() {}
+};
+Packed p;
+
+
+// 1 byte total
+struct Empty {
+ unsigned int : 0;
+ ~Empty() {}
+};
+Empty e;
+
+
+// 4 byte total
+struct Simple {
+ unsigned int a : 1;
+ ~Simple() {}
+};
+Simple s;
+
+
+// 8 bytes total
+struct Anon {
+ // 1 byte
+ unsigned int a : 1;
+ unsigned int b : 2;
+ // Force alignment to next byte
+ unsigned int : 0;
+ unsigned int c : 1;
+ ~Anon() {}
+};
+Anon an;
+
+
+struct CharStruct {
+ char c;
+ ~CharStruct();
+};
+
+struct Adjacent {
+ CharStruct a;
+ int b : 1;
+ CharStruct c;
+ ~Adjacent() {}
+};
+Adjacent ad;
+
+
+// CHECK-LABEL: define {{.*}}PackedD2Ev
+// CHECK: call void @__sanitizer_dtor_callback{{.*}}i64 17
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}EmptyD2Ev
+// CHECK-NOT: call void @__sanitizer_dtor_callback{{.*}}i64 0
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}SimpleD2Ev
+// CHECK: call void @__sanitizer_dtor_callback{{.*}}i64 1
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}AnonD2Ev
+// CHECK: call void @__sanitizer_dtor_callback{{.*}}i64 5
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}AdjacentD2Ev
+// CHECK: call void @__sanitizer_dtor_callback{{.*}}i64 1
+// CHECK: ret void
diff --git a/src/llvm-project/clang/test/CodeGenCXX/sanitize-dtor-callback.cpp b/src/llvm-project/clang/test/CodeGenCXX/sanitize-dtor-callback.cpp
new file mode 100644
index 0000000..ecb0f2b
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/sanitize-dtor-callback.cpp
@@ -0,0 +1,73 @@
+// Test -fsanitize-memory-use-after-dtor
+// RUN: %clang_cc1 -fsanitize=memory -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+// Sanitizing dtor is emitted in dtor for every class, and only
+// poisons once.
+
+struct Simple {
+ int x;
+ ~Simple() {}
+};
+Simple s;
+// Simple internal member is poisoned by compiler-generated dtor
+// CHECK-LABEL: define {{.*}}SimpleD1Ev
+// CHECK: call void {{.*}}SimpleD2Ev
+// CHECK: ret void
+
+struct Inlined {
+ int y;
+ inline ~Inlined() {}
+};
+Inlined i;
+// Simple internal member is poisoned by compiler-generated dtor
+// CHECK-LABEL: define {{.*}}InlinedD1Ev
+// CHECK: call void {{.*}}InlinedD2Ev
+// CHECK: ret void
+
+struct Defaulted_Trivial {
+ ~Defaulted_Trivial() = default;
+};
+void create_def_trivial() {
+ Defaulted_Trivial def_trivial;
+}
+// The compiler is explicitly signalled to handle object cleanup.
+// No complex member attributes. Compiler destroys inline, so
+// no destructor defined.
+// CHECK-LABEL: define {{.*}}create_def_trivial
+// CHECK-NOT: call {{.*}}Defaulted_Trivial
+// CHECK: ret void
+
+struct Defaulted_Non_Trivial {
+ Simple s;
+ ~Defaulted_Non_Trivial() = default;
+};
+Defaulted_Non_Trivial def_non_trivial;
+// Explicitly compiler-generated dtor poisons object.
+// By including a Simple member in the struct, the compiler is
+// forced to generate a non-trivial destructor.
+// CHECK-LABEL: define {{.*}}Defaulted_Non_TrivialD1Ev
+// CHECK: call void {{.*}}Defaulted_Non_TrivialD2
+// CHECK: ret void
+
+
+// Note: ordering is important. In the emitted bytecode, these
+// second dtors defined after the first. Explicitly checked here
+// to confirm that all invoked dtors have member poisoning
+// instrumentation inserted.
+// CHECK-LABEL: define {{.*}}SimpleD2Ev
+// CHECK-NOT: store i{{[0-9]+}} 0, {{.*}}@__msan_param_tls
+// CHECK: call void @__sanitizer_dtor_callback
+// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}InlinedD2Ev
+// CHECK-NOT: store i{{[0-9]+}} 0, {{.*}}@__msan_param_tls
+// CHECK: call void @__sanitizer_dtor_callback
+// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}Defaulted_Non_TrivialD2Ev
+// CHECK-NOT: store i{{[0-9]+}} 0, {{.*}}@__msan_param_tls
+// CHECK: call void @__sanitizer_dtor_callback
+// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: ret void
diff --git a/src/llvm-project/clang/test/CodeGenCXX/sanitize-dtor-derived-class.cpp b/src/llvm-project/clang/test/CodeGenCXX/sanitize-dtor-derived-class.cpp
new file mode 100644
index 0000000..618096a
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/sanitize-dtor-derived-class.cpp
@@ -0,0 +1,71 @@
+// RUN: %clang_cc1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-passes -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-passes -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+// Base dtor poisons members
+// Complete dtor poisons vtable ptr after destroying members and
+// virtual bases
+
+class Base {
+ public:
+ int x;
+ Base() {
+ x = 5;
+ }
+ virtual ~Base() {
+ x += 1;
+ }
+};
+
+class Derived : public Base {
+ public:
+ int y;
+ Derived() {
+ y = 10;
+ }
+ ~Derived() {
+ y += 1;
+ }
+};
+
+Derived d;
+
+// Invoke base destructor. No vtable pointer to poison.
+// CHECK-LABEL: define {{.*}}DerivedD1Ev
+// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: call void {{.*}}DerivedD2Ev
+// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}DerivedD0Ev
+// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: call void {{.*}}DerivedD1Ev
+// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: ret void
+
+// Invokes base destructor, and poison vtable pointer.
+// CHECK-LABEL: define {{.*}}BaseD1Ev
+// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: call void {{.*}}BaseD2Ev
+// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}BaseD0Ev
+// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: call void {{.*}}BaseD1Ev
+// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: ret void
+
+// Poison members and vtable ptr.
+// CHECK-LABEL: define {{.*}}BaseD2Ev
+// CHECK: call void @__sanitizer_dtor_callback
+// CHECK: call void @__sanitizer_dtor_callback{{.*}}i64 8
+// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: ret void
+
+// Poison members and destroy non-virtual base.
+// CHECK-LABEL: define {{.*}}DerivedD2Ev
+// CHECK: call void @__sanitizer_dtor_callback
+// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: call void {{.*}}BaseD2Ev
+// CHECK: call void @__sanitizer_dtor_callback{{.*}}i64 8
+// CHECK: ret void
diff --git a/src/llvm-project/clang/test/CodeGenCXX/sanitize-dtor-fn-attribute.cpp b/src/llvm-project/clang/test/CodeGenCXX/sanitize-dtor-fn-attribute.cpp
new file mode 100644
index 0000000..4af2677
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/sanitize-dtor-fn-attribute.cpp
@@ -0,0 +1,43 @@
+// Test -fsanitize-memory-use-after-dtor
+// RUN: %clang_cc1 -fsanitize=memory -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+// The no_sanitize_memory attribute, when applied to a destructor,
+// represses emission of sanitizing callback
+
+template <class T> class Vector {
+ public:
+ int size;
+ ~Vector() {}
+};
+
+struct No_San {
+ Vector<int> v;
+ int x;
+ No_San() { }
+ __attribute__((no_sanitize_memory)) ~No_San() = default;
+};
+
+int main() {
+ No_San *ns = new No_San();
+ ns->~No_San();
+ return 0;
+}
+
+// Repressing the sanitization attribute results in no msan
+// instrumentation of the destructor
+// CHECK: define {{.*}}No_SanD1Ev{{.*}} [[ATTRIBUTE:#[0-9]+]]
+// CHECK-NOT: call void {{.*}}sanitizer_dtor_callback
+// CHECK: ret void
+
+// CHECK: define {{.*}}No_SanD2Ev{{.*}} [[ATTRIBUTE:#[0-9]+]]
+// CHECK-NOT: call void {{.*}}sanitizer_dtor_callback
+// CHECK: call void {{.*}}VectorIiED2Ev
+// CHECK-NOT: call void {{.*}}sanitizer_dtor_callback
+// CHECK: ret void
+
+// CHECK: define {{.*}}VectorIiED2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback
+// CHECK: ret void
+
+// When attribute is repressed, the destructor does not emit any tail calls
+// CHECK-NOT: attributes [[ATTRIBUTE]] = {{.*}} sanitize_memory
diff --git a/src/llvm-project/clang/test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp b/src/llvm-project/clang/test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
new file mode 100644
index 0000000..27eb64b
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -fsanitize=memory -O0 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fsanitize=memory -O1 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+template <class T>
+class Vector {
+public:
+ int size;
+ ~Vector() {
+ size += 1;
+ }
+};
+
+struct Base {
+ int b1;
+ double b2;
+ Base() {
+ b1 = 5;
+ b2 = 10.989;
+ }
+ virtual ~Base() {}
+};
+
+struct VirtualBase {
+ int vb1;
+ int vb2;
+ VirtualBase() {
+ vb1 = 10;
+ vb2 = 11;
+ }
+ virtual ~VirtualBase() {}
+};
+
+struct Derived : public Base, public virtual VirtualBase {
+ int d1;
+ Vector<int> v;
+ int d2;
+ Derived() {
+ d1 = 10;
+ }
+ ~Derived() {}
+};
+
+Derived d;
+
+// Destruction order:
+// Derived: int, Vector, Base, VirtualBase
+
+// CHECK-LABEL: define {{.*}}ZN7DerivedD1Ev
+// CHECK: call void {{.*}}ZN11VirtualBaseD2Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN7DerivedD0Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD1Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD0Ev
+// CHECK: ret void
+
+// poison 2 ints
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 8)
+// CHECK: ret void
+
+// poison int and double
+// CHECK-LABEL: define {{.*}}ZN4BaseD2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 16)
+// CHECK: ret void
+
+// poison int, ignore vector, poison int
+// CHECK-LABEL: define {{.*}}ZN7DerivedD2Ev
+// CHECK: call void {{.*}}ZN6VectorIiED1Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4)
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4)
+// CHECK: call void {{.*}}ZN4BaseD2Ev
+// CHECK: ret void
+
+// poison int
+// CHECK-LABEL: define {{.*}}ZN6VectorIiED2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4)
+// CHECK: ret void
diff --git a/src/llvm-project/clang/test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp b/src/llvm-project/clang/test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp
new file mode 100644
index 0000000..28624a0
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp
@@ -0,0 +1,30 @@
+// Test -fsanitize-memory-use-after-dtor
+// RUN: %clang_cc1 -fsanitize=memory -O1 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fsanitize=memory -O2 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+template <class T>
+class Vector {
+public:
+ int size;
+ ~Vector() {}
+};
+
+// Virtual function table for the derived class only contains
+// its own destructors, with no aliasing to base class dtors.
+struct Base {
+ Vector<int> v;
+ int x;
+ Base() { x = 5; }
+ virtual ~Base() {}
+};
+
+struct Derived : public Base {
+ int z;
+ Derived() { z = 10; }
+ ~Derived() {}
+};
+
+Derived d;
+
+// Definition of virtual function table
+// CHECK: @_ZTV7Derived = {{.*}}@_ZN7DerivedD1Ev{{.*}}@_ZN7DerivedD0Ev
diff --git a/src/llvm-project/clang/test/CodeGenCXX/sanitize-dtor-tail-call.cpp b/src/llvm-project/clang/test/CodeGenCXX/sanitize-dtor-tail-call.cpp
new file mode 100644
index 0000000..d6f5719
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/sanitize-dtor-tail-call.cpp
@@ -0,0 +1,23 @@
+// Test -fsanitize-memory-use-after-dtor
+// RUN: %clang_cc1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-passes -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-passes -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+struct Simple {
+ int x_;
+ Simple() {
+ x_ = 5;
+ }
+ ~Simple() {
+ x_ += 1;
+ }
+};
+
+Simple s;
+// Simple internal member is poisoned by compiler-generated dtor
+// CHECK: define {{.*}}SimpleD2Ev{{.*}} [[ATTRIBUTE:#[0-9]+]]
+// CHECK: {{^ *}}call void @__sanitizer_dtor_callback
+// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: ret void
+
+// Destructor does not emit any tail calls
+// CHECK: attributes [[ATTRIBUTE]] = {{.*}}"disable-tail-calls"="true"
diff --git a/src/llvm-project/clang/test/CodeGenCXX/sanitize-dtor-trivial.cpp b/src/llvm-project/clang/test/CodeGenCXX/sanitize-dtor-trivial.cpp
new file mode 100644
index 0000000..9e328c0
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/sanitize-dtor-trivial.cpp
@@ -0,0 +1,15 @@
+// Test -fsanitize-memory-use-after-dtor
+// RUN: %clang_cc1 -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-passes -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-passes -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+// TODO Success pending on resolution of issue:
+// https://github.com/google/sanitizers/issues/596
+// XFAIL: *
+
+struct Trivial {
+ int a;
+ int b;
+};
+Trivial t;
+
+// CHECK: call void @__sanitizer_dtor_callback
diff --git a/src/llvm-project/clang/test/CodeGenCXX/sanitize-dtor-vtable.cpp b/src/llvm-project/clang/test/CodeGenCXX/sanitize-dtor-vtable.cpp
new file mode 100644
index 0000000..2318ef0
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/sanitize-dtor-vtable.cpp
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-passes -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-passes -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+class A {
+ public:
+ int x;
+ A() {}
+ virtual ~A() {}
+};
+A a;
+
+class B : virtual public A {
+ public:
+ int y;
+ B() {}
+ ~B() {}
+};
+B b;
+
+// CHECK-LABEL: define {{.*}}AD1Ev
+// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: call void {{.*}}AD2Ev
+// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: ret void
+
+// After invoking base dtor and dtor for virtual base, poison vtable ptr.
+// CHECK-LABEL: define {{.*}}BD1Ev
+// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: call void {{.*}}BD2Ev
+// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: call void {{.*}}AD2Ev
+// CHECK: call void @__sanitizer_dtor_callback{{.*}}i64 8
+// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: ret void
+
+// Since no virtual bases, poison vtable ptr here.
+// CHECK-LABEL: define {{.*}}AD2Ev
+// CHECK: call void @__sanitizer_dtor_callback
+// CHECK: call void @__sanitizer_dtor_callback{{.*}}i64 8
+// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: ret void
+
+// Poison members
+// CHECK-LABEL: define {{.*}}BD2Ev
+// CHECK: call void @__sanitizer_dtor_callback
+// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: ret void
diff --git a/src/llvm-project/clang/test/CodeGenCXX/sanitize-no-dtor-callback.cpp b/src/llvm-project/clang/test/CodeGenCXX/sanitize-no-dtor-callback.cpp
new file mode 100644
index 0000000..afc5382
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/sanitize-no-dtor-callback.cpp
@@ -0,0 +1,25 @@
+// Test with the flag -fno-sanitize-memory-use-after-dtor, to ensure that
+// instrumentation is not erroneously inserted
+// RUN: %clang_cc1 -fsanitize=memory -fno-sanitize-memory-use-after-dtor -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+struct Simple {
+ int x;
+ ~Simple() {}
+};
+Simple s;
+// CHECK-LABEL: define {{.*}}SimpleD1Ev
+// CHECK-NOT: call void @__sanitizer_dtor_callback
+
+struct Inlined {
+ int x;
+ inline ~Inlined() {}
+};
+Inlined i;
+// CHECK-LABEL: define {{.*}}InlinedD1Ev
+// CHECK-NOT: call void @__sanitizer_dtor_callback
+
+// CHECK-LABEL: define {{.*}}SimpleD2Ev
+// CHECK-NOT: call void @__sanitizer_dtor_callback
+
+// CHECK-LABEL: define {{.*}}InlinedD2Ev
+// CHECK-NOT: call void @__sanitizer_dtor_callback
diff --git a/src/llvm-project/clang/test/CodeGenCXX/scoped-enums-debug-info.cpp b/src/llvm-project/clang/test/CodeGenCXX/scoped-enums-debug-info.cpp
new file mode 100644
index 0000000..131e31b
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/scoped-enums-debug-info.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -std=c++11 -emit-llvm -debug-info-kind=limited -o - %s | FileCheck %s
+// Test that we are emitting debug info and base types for scoped enums.
+
+// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "Color"
+// CHECK-SAME: baseType: ![[INT:[0-9]+]]
+// CHECK: ![[INT]] = !DIBasicType(name: "int"
+enum class Color { gray };
+
+void f(Color);
+void g() {
+ f(Color::gray);
+}
+
+// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "Colour"
+// CHECK-SAME: baseType: ![[INT]]
+enum struct Colour { grey };
+
+void h(Colour);
+void i() {
+ h(Colour::grey);
+}
+
+// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "Couleur"
+// CHECK-SAME: baseType: ![[UCHAR:[0-9]+]]
+// CHECK: ![[UCHAR]] = !DIBasicType(name: "unsigned char"
+enum class Couleur : unsigned char { gris };
+
+void j(Couleur);
+void k() {
+ j(Couleur::gris);
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/scoped-enums.cpp b/src/llvm-project/clang/test/CodeGenCXX/scoped-enums.cpp
new file mode 100644
index 0000000..218013a
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/scoped-enums.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
+
+// PR9923
+enum class Color { red, blue, green };
+
+void f(Color);
+void g() {
+ f(Color::red);
+}
+
+// See that struct is handled equally.
+enum struct Colour { grey };
+
+void h(Colour);
+void i() {
+ h(Colour::grey);
+}
+
+enum struct PR17103 : int { a = -1, b = 1 };
+bool cmp(PR17103 x, PR17103 y) { return x < y; }
+
+// CHECK-LABEL: @_Z3cmp7PR17103S_(
+// CHECK-NOT: }
+// CHECK: icmp slt
diff --git a/src/llvm-project/clang/test/CodeGenCXX/sections.cpp b/src/llvm-project/clang/test/CodeGenCXX/sections.cpp
new file mode 100644
index 0000000..899bdfa
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/sections.cpp
@@ -0,0 +1,101 @@
+// RUN: %clang_cc1 -emit-llvm -triple i686-pc-win32 -fms-extensions -o - %s | FileCheck %s
+
+extern "C" {
+
+#pragma const_seg(".my_const")
+#pragma bss_seg(".my_bss")
+int D = 1;
+#pragma data_seg(".data")
+int a = 1;
+#pragma data_seg(push, label, ".data2")
+extern const int b;
+const int b = 1;
+const char* s = "my string!";
+#pragma data_seg(push, ".my_seg")
+int c = 1;
+#pragma data_seg(pop, label)
+int d = 1;
+int e;
+#pragma bss_seg(".c")
+int f;
+void g(void){}
+#pragma code_seg(".my_code")
+void h(void){}
+#pragma bss_seg()
+int i;
+#pragma bss_seg(".bss1")
+#pragma bss_seg(push, test, ".bss2")
+#pragma bss_seg()
+#pragma bss_seg()
+int TEST1;
+#pragma bss_seg(pop)
+int TEST2;
+
+
+// Check "save-restore" of pragma stacks.
+struct Outer {
+ void f() {
+ #pragma bss_seg(push, ".bss3")
+ #pragma code_seg(push, ".my_code1")
+ #pragma const_seg(push, ".my_const1")
+ #pragma data_seg(push, ".data3")
+ struct Inner {
+ void g() {
+ #pragma bss_seg(push, ".bss4")
+ #pragma code_seg(push, ".my_code2")
+ #pragma const_seg(push, ".my_const2")
+ #pragma data_seg(push, ".data4")
+ }
+ };
+ }
+};
+
+void h2(void) {} // should be in ".my_code"
+int TEST3; // should be in ".bss1"
+int d2 = 1; // should be in ".data"
+extern const int b2; // should be in ".my_const"
+const int b2 = 1;
+
+#pragma section("read_flag_section", read)
+// Even though they are not declared const, these become constant since they are
+// in a read-only section.
+__declspec(allocate("read_flag_section")) int unreferenced = 0;
+extern __declspec(allocate("read_flag_section")) int referenced = 42;
+int *user() { return &referenced; }
+
+#pragma section("no_section_attributes")
+// A pragma section with no section attributes is read/write.
+__declspec(allocate("no_section_attributes")) int implicitly_read_write = 42;
+
+#pragma section("long_section", long)
+// Pragma section ignores "long".
+__declspec(allocate("long_section")) long long_var = 42;
+
+#pragma section("short_section", short)
+// Pragma section ignores "short".
+__declspec(allocate("short_section")) short short_var = 42;
+}
+
+//CHECK: @D = dso_local global i32 1
+//CHECK: @a = dso_local global i32 1, section ".data"
+//CHECK: @b = dso_local constant i32 1, section ".my_const"
+//CHECK: @[[MYSTR:.*]] = {{.*}} unnamed_addr constant [11 x i8] c"my string!\00"
+//CHECK: @s = dso_local global i8* getelementptr inbounds ([11 x i8], [11 x i8]* @[[MYSTR]], i32 0, i32 0), section ".data2"
+//CHECK: @c = dso_local global i32 1, section ".my_seg"
+//CHECK: @d = dso_local global i32 1, section ".data"
+//CHECK: @e = dso_local global i32 0, section ".my_bss"
+//CHECK: @f = dso_local global i32 0, section ".c"
+//CHECK: @i = dso_local global i32 0
+//CHECK: @TEST1 = dso_local global i32 0
+//CHECK: @TEST2 = dso_local global i32 0, section ".bss1"
+//CHECK: @TEST3 = dso_local global i32 0, section ".bss1"
+//CHECK: @d2 = dso_local global i32 1, section ".data"
+//CHECK: @b2 = dso_local constant i32 1, section ".my_const"
+//CHECK: @unreferenced = dso_local constant i32 0, section "read_flag_section"
+//CHECK: @referenced = dso_local constant i32 42, section "read_flag_section"
+//CHECK: @implicitly_read_write = dso_local global i32 42, section "no_section_attributes"
+//CHECK: @long_var = dso_local global i32 42, section "long_section"
+//CHECK: @short_var = dso_local global i16 42, section "short_section"
+//CHECK: define dso_local void @g()
+//CHECK: define dso_local void @h() {{.*}} section ".my_code"
+//CHECK: define dso_local void @h2() {{.*}} section ".my_code"
diff --git a/src/llvm-project/clang/test/CodeGenCXX/sizeof-unwind-exception.cpp b/src/llvm-project/clang/test/CodeGenCXX/sizeof-unwind-exception.cpp
new file mode 100644
index 0000000..d2a1c33
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/sizeof-unwind-exception.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fcxx-exceptions -fexceptions %s -O2 -o - | FileCheck %s --check-prefix=X86-64
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fcxx-exceptions -fexceptions %s -O2 -o - | FileCheck %s --check-prefix=X86-32
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fcxx-exceptions -fexceptions %s -O2 -o - | FileCheck %s --check-prefix=ARM-DARWIN
+// RUN: %clang_cc1 -triple arm-unknown-gnueabi -emit-llvm -fcxx-exceptions -fexceptions %s -O2 -o - | FileCheck %s --check-prefix=ARM-EABI
+// RUN: %clang_cc1 -triple mipsel-unknown-unknown -emit-llvm -fcxx-exceptions -fexceptions %s -O2 -o - | FileCheck %s --check-prefix=MIPS
+
+void foo();
+void test() {
+ try {
+ foo();
+ } catch (int *&i) {
+ *i = 5;
+ }
+}
+
+// PR10789: different platforms have different sizes for struct UnwindException.
+
+// X86-64: [[T0:%.*]] = tail call i8* @__cxa_begin_catch(i8* [[EXN:%.*]]) [[NUW:#[0-9]+]]
+// X86-64-NEXT: [[T1:%.*]] = getelementptr i8, i8* [[EXN]], i64 32
+// X86-32: [[T0:%.*]] = tail call i8* @__cxa_begin_catch(i8* [[EXN:%.*]]) [[NUW:#[0-9]+]]
+// X86-32-NEXT: [[T1:%.*]] = getelementptr i8, i8* [[EXN]], i64 32
+// ARM-DARWIN: [[T0:%.*]] = tail call i8* @__cxa_begin_catch(i8* [[EXN:%.*]]) [[NUW:#[0-9]+]]
+// ARM-DARWIN-NEXT: [[T1:%.*]] = getelementptr i8, i8* [[EXN]], i64 32
+// ARM-EABI: [[T0:%.*]] = tail call i8* @__cxa_begin_catch(i8* [[EXN:%.*]]) [[NUW:#[0-9]+]]
+// ARM-EABI-NEXT: [[T1:%.*]] = getelementptr i8, i8* [[EXN]], i32 88
+// MIPS: [[T0:%.*]] = tail call i8* @__cxa_begin_catch(i8* [[EXN:%.*]]) [[NUW:#[0-9]+]]
+// MIPS-NEXT: [[T1:%.*]] = getelementptr i8, i8* [[EXN]], i32 24
+
+// X86-64: attributes [[NUW]] = { nounwind }
+// X86-32: attributes [[NUW]] = { nounwind }
+// ARM-DARWIN: attributes [[NUW]] = { nounwind }
+// ARM-EABI: attributes [[NUW]] = { nounwind }
+// MIPS: attributes [[NUW]] = { nounwind }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp b/src/llvm-project/clang/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp
new file mode 100644
index 0000000..83a2d61
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp
@@ -0,0 +1,200 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+// See Test9 for test description.
+// CHECK: @_ZTTN5Test91BE = linkonce_odr unnamed_addr constant
+namespace Test1 {
+
+// Check that we don't initialize the vtable pointer in A::~A(), since the destructor body is trivial.
+struct A {
+ virtual void f();
+ ~A();
+};
+
+// CHECK-LABEL: define void @_ZN5Test11AD2Ev
+// CHECK-NOT: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN5Test11AE, i64 0, i64 2) to i32 (...)**), i32 (...)***
+A::~A()
+{
+}
+
+}
+
+namespace Test2 {
+
+// Check that we do initialize the vtable pointer in A::~A() since the destructor body isn't trivial.
+struct A {
+ virtual void f();
+ ~A();
+};
+
+// CHECK-LABEL: define void @_ZN5Test21AD2Ev
+// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN5Test21AE, i32 0, inrange i32 0, i32 2) to i32 (...)**), i32 (...)***
+A::~A() {
+ f();
+}
+
+}
+
+namespace Test3 {
+
+// Check that we don't initialize the vtable pointer in A::~A(), since the destructor body is trivial
+// and Field's destructor body is also trivial.
+struct Field {
+ ~Field() { }
+};
+
+struct A {
+ virtual void f();
+ ~A();
+
+ Field field;
+};
+
+// CHECK-LABEL: define void @_ZN5Test31AD2Ev
+// CHECK-NOT: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN5Test31AE, i32 0, inrange i32 0, i32 2) to i32 (...)**), i32 (...)***
+A::~A() {
+
+}
+
+}
+
+namespace Test4 {
+
+// Check that we do initialize the vtable pointer in A::~A(), since Field's destructor body
+// isn't trivial.
+
+void f();
+
+struct Field {
+ ~Field() { f(); }
+};
+
+struct A {
+ virtual void f();
+ ~A();
+
+ Field field;
+};
+
+// CHECK-LABEL: define void @_ZN5Test41AD2Ev
+// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN5Test41AE, i32 0, inrange i32 0, i32 2) to i32 (...)**), i32 (...)***
+A::~A()
+{
+}
+
+}
+
+namespace Test5 {
+
+// Check that we do initialize the vtable pointer in A::~A(), since Field's destructor isn't
+// available in this translation unit.
+
+struct Field {
+ ~Field();
+};
+
+struct A {
+ virtual void f();
+ ~A();
+
+ Field field;
+};
+
+// CHECK-LABEL: define void @_ZN5Test51AD2Ev
+// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN5Test51AE, i32 0, inrange i32 0, i32 2) to i32 (...)**), i32 (...)***
+A::~A()
+{
+}
+
+}
+
+namespace Test6 {
+
+// Check that we do initialize the vtable pointer in A::~A(), since Field has a member
+// variable with a non-trivial destructor body.
+
+struct NonTrivialDestructorBody {
+ ~NonTrivialDestructorBody();
+};
+
+struct Field {
+ NonTrivialDestructorBody nonTrivialDestructorBody;
+};
+
+struct A {
+ virtual void f();
+ ~A();
+
+ Field field;
+};
+
+// CHECK-LABEL: define void @_ZN5Test61AD2Ev
+// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN5Test61AE, i32 0, inrange i32 0, i32 2) to i32 (...)**), i32 (...)***
+A::~A()
+{
+}
+
+}
+
+namespace Test7 {
+
+// Check that we do initialize the vtable pointer in A::~A(), since Field has a base
+// class with a non-trivial destructor body.
+
+struct NonTrivialDestructorBody {
+ ~NonTrivialDestructorBody();
+};
+
+struct Field : NonTrivialDestructorBody { };
+
+struct A {
+ virtual void f();
+ ~A();
+
+ Field field;
+};
+
+// CHECK-LABEL: define void @_ZN5Test71AD2Ev
+// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN5Test71AE, i32 0, inrange i32 0, i32 2) to i32 (...)**), i32 (...)***
+A::~A()
+{
+}
+
+}
+
+namespace Test8 {
+
+// Check that we do initialize the vtable pointer in A::~A(), since Field has a virtual base
+// class with a non-trivial destructor body.
+
+struct NonTrivialDestructorBody {
+ ~NonTrivialDestructorBody();
+};
+
+struct Field : virtual NonTrivialDestructorBody { };
+
+struct A {
+ virtual void f();
+ ~A();
+
+ Field field;
+};
+
+// CHECK-LABEL: define void @_ZN5Test81AD2Ev
+// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN5Test81AE, i32 0, inrange i32 0, i32 2) to i32 (...)**), i32 (...)***
+A::~A()
+{
+}
+
+}
+
+namespace Test9 {
+
+// Check that we emit a VTT for B, even though we don't initialize the vtable pointer in the destructor.
+struct A { virtual ~A () { } };
+struct B : virtual A {};
+struct C : virtual B {
+ virtual ~C();
+};
+C::~C() {}
+
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/sparcv9-abi.cpp b/src/llvm-project/clang/test/CodeGenCXX/sparcv9-abi.cpp
new file mode 100644
index 0000000..128d648
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/sparcv9-abi.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple sparcv9-unknown-unknown -emit-llvm %s -o - | FileCheck %s
+
+struct pod {
+ int a, b;
+};
+
+void f0();
+void f1(struct pod);
+
+struct notpod {
+ int a, b;
+ ~notpod() { f0(); }
+};
+
+void f2(struct notpod);
+
+// CHECK-LABEL: caller
+// CHECK: call void @_Z2f13pod(i64
+// CHECK: call void @_Z2f26notpod(%struct.notpod*
+void caller()
+{
+ pod p1;
+ notpod p2;
+ f1(p1);
+ f2(p2);
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/specialized-static-data-mem-init.cpp b/src/llvm-project/clang/test/CodeGenCXX/specialized-static-data-mem-init.cpp
new file mode 100644
index 0000000..d793242
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/specialized-static-data-mem-init.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 %s -emit-llvm -triple %itanium_abi_triple -o - | FileCheck %s
+// rdar: // 8562966
+// pr8409
+
+// CHECK: @_ZN1CIiE11needs_guardE = linkonce_odr {{(dso_local )?}}global
+// CHECK: @_ZGVN1CIiE11needs_guardE = linkonce_odr {{(dso_local )?}}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/src/llvm-project/clang/test/CodeGenCXX/speculative-vtt.cpp b/src/llvm-project/clang/test/CodeGenCXX/speculative-vtt.cpp
new file mode 100644
index 0000000..120d95d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/speculative-vtt.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu %s -O2 -disable-llvm-passes -emit-llvm -o - | FileCheck %s
+struct A { virtual ~A(); };
+template<typename T> struct B : virtual A {
+ ~B() override {}
+};
+struct C : B<int>, B<float> { C(); ~C() override; };
+struct D : C { ~D() override; };
+
+// We must not create a reference to B<int>::~B() here, because we're not going to emit it.
+// CHECK-NOT: @_ZN1BIiED1Ev
+// CHECK-NOT: @_ZTC1D0_1BIiE =
+// CHECK-NOT: @_ZTT1D = available_externally
+D *p = new D;
diff --git a/src/llvm-project/clang/test/CodeGenCXX/split-stacks.cpp b/src/llvm-project/clang/test/CodeGenCXX/split-stacks.cpp
new file mode 100644
index 0000000..2373bcc
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/split-stacks.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang -target x86_64-linux-gnu -fsplit-stack -S -std=c++11 %s -emit-llvm -o - | FileCheck -check-prefix=CHECK-SEGSTK %s
+// RUN: %clang -target x86_64-linux-gnu -S -std=c++11 %s -emit-llvm -o - | FileCheck -check-prefix=CHECK-NOSEGSTK %s
+
+int foo() {
+ return 0;
+}
+
+template <typename T>
+[[gnu::no_split_stack]]
+int tnosplit() {
+ return 0;
+}
+
+[[gnu::no_split_stack]]
+int nosplit() {
+ return tnosplit<int>();
+}
+
+// CHECK-SEGSTK: define dso_local i32 @_Z3foov() [[SS:#[0-9]+]] {
+// CHECK-SEGSTK: define dso_local i32 @_Z7nosplitv() [[NSS1:#[0-9]+]] {
+// CHECK-SEGSTK: define linkonce_odr dso_local i32 @_Z8tnosplitIiEiv() [[NSS2:#[0-9]+]] comdat {
+// CHECK-SEGSTK-NOT: [[NSS1]] = { {{.*}} "split-stack" {{.*}} }
+// CHECK-SEGSTK-NOT: [[NSS2]] = { {{.*}} "split-stack" {{.*}} }
+// CHECK-SEGSTK: [[SS]] = { {{.*}} "split-stack" {{.*}} }
+// CHECK-SEGSTK-NOT: [[NSS1]] = { {{.*}} "split-stack" {{.*}} }
+// CHECK-SEGSTK-NOT: [[NSS2]] = { {{.*}} "split-stack" {{.*}} }
+
+// CHECK-NOSEGSTK: define dso_local i32 @_Z3foov() [[NSS0:#[0-9]+]] {
+// CHECK-NOSEGSTK: define dso_local i32 @_Z7nosplitv() [[NSS1:#[0-9]+]] {
+// CHECK-NOSEGSTK: define linkonce_odr dso_local i32 @_Z8tnosplitIiEiv() [[NSS2:#[0-9]+]] comdat {
+// CHECK-NOSEGSTK-NOT: [[NSS1]] = { {{.*}} "split-stack" {{.*}} }
+// CHECK-NOSEGSTK-NOT: [[NSS2]] = { {{.*}} "split-stack" {{.*}} }
+// CHECK-NOSEGSTK-NOT: [[NSS3]] = { {{.*}} "split-stack" {{.*}} }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/stack-reuse-exceptions.cpp b/src/llvm-project/clang/test/CodeGenCXX/stack-reuse-exceptions.cpp
new file mode 100644
index 0000000..de870c5
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/stack-reuse-exceptions.cpp
@@ -0,0 +1,189 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu %s -o - -emit-llvm -O1 \
+// RUN: -fexceptions -fcxx-exceptions | FileCheck %s
+//
+// We should emit lifetime.ends for these temporaries in both the 'exception'
+// and 'normal' paths in functions.
+//
+// -O1 is necessary to make lifetime markers appear.
+
+struct Large {
+ int cs[32];
+};
+
+Large getLarge();
+
+// Used to ensure we emit invokes.
+struct NontrivialDtor {
+ int i;
+ ~NontrivialDtor();
+};
+
+// CHECK-LABEL: define void @_Z33cleanupsAreEmittedWithoutTryCatchv
+void cleanupsAreEmittedWithoutTryCatch() {
+// CHECK: %[[CLEAN:[^ ]+]] = bitcast %struct.NontrivialDtor* %{{[^ ]+}} to i8*
+// CHECK: call void @llvm.lifetime.start.p0i8({{[^,]+}}, i8* nonnull %[[CLEAN]])
+// CHECK: %[[T1:[^ ]+]] = bitcast %struct.Large* %{{[^ ]+}} to i8*
+// CHECK: call void @llvm.lifetime.start.p0i8({{[^,]+}}, i8* nonnull %[[T1]])
+// CHECK-NEXT: invoke void @_Z8getLargev
+// CHECK-NEXT: to label %[[CONT:[^ ]+]] unwind label %[[LPAD:[^ ]+]]
+//
+// CHECK: [[CONT]]:
+// CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[T1]])
+// CHECK: %[[T2:[^ ]+]] = bitcast %struct.Large* %{{[^ ]+}} to i8*
+// CHECK: call void @llvm.lifetime.start.p0i8({{[^,]+}}, i8* nonnull %[[T2]])
+// CHECK-NEXT: invoke void @_Z8getLargev
+// CHECK-NEXT: to label %[[CONT2:[^ ]+]] unwind label %[[LPAD2:.+]]
+//
+// CHECK: [[CONT2]]:
+// CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[T2]])
+// CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[CLEAN]])
+// CHECK: ret void
+//
+// CHECK: [[LPAD]]:
+// CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[T1]])
+// CHECK: br label %[[EHCLEANUP:.+]]
+//
+// CHECK: [[LPAD2]]:
+// CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[T2]])
+// CHECK: br label %[[EHCLEANUP]]
+//
+// CHECK: [[EHCLEANUP]]:
+// CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[CLEAN]])
+
+ NontrivialDtor clean;
+
+ getLarge();
+ getLarge();
+}
+
+// CHECK-LABEL: define void @_Z30cleanupsAreEmittedWithTryCatchv
+void cleanupsAreEmittedWithTryCatch() {
+// CHECK: %[[CLEAN:[^ ]+]] = bitcast %struct.NontrivialDtor* %{{[^ ]+}} to i8*
+// CHECK: call void @llvm.lifetime.start.p0i8({{[^,]+}}, i8* nonnull %[[CLEAN]])
+// CHECK: %[[T1:[^ ]+]] = bitcast %struct.Large* %{{[^ ]+}} to i8*
+// CHECK: call void @llvm.lifetime.start.p0i8({{[^,]+}}, i8* nonnull %[[T1]])
+// CHECK-NEXT: invoke void @_Z8getLargev
+// CHECK-NEXT: to label %[[CONT:[^ ]+]] unwind label %[[LPAD:[^ ]+]]
+//
+// CHECK: [[CONT]]:
+// CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[T1]])
+// CHECK: %[[T2:[^ ]+]] = bitcast %struct.Large* %{{[^ ]+}} to i8*
+// CHECK: call void @llvm.lifetime.start.p0i8({{[^,]+}}, i8* nonnull %[[T2]])
+// CHECK-NEXT: invoke void @_Z8getLargev
+// CHECK-NEXT: to label %[[CONT2:[^ ]+]] unwind label %[[LPAD2:.+]]
+//
+// CHECK: [[CONT2]]:
+// CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[T2]])
+// CHECK: br label %[[TRY_CONT:.+]]
+//
+// CHECK: [[LPAD]]:
+// CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[T1]])
+// CHECK: br label %[[CATCH:.+]]
+//
+// CHECK: [[LPAD2]]:
+// CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[T2]])
+// CHECK: br label %[[CATCH]]
+//
+// CHECK: [[CATCH]]:
+// CHECK-NOT: call void @llvm.lifetime
+// CHECK: invoke void
+// CHECK-NEXT: to label %[[TRY_CONT]] unwind label %[[OUTER_LPAD:.+]]
+//
+// CHECK: [[TRY_CONT]]:
+// CHECK: %[[T_OUTER:[^ ]+]] = bitcast %struct.Large* %{{[^ ]+}} to i8*
+// CHECK: call void @llvm.lifetime.start.p0i8({{[^,]+}}, i8* nonnull %[[T_OUTER]])
+// CHECK-NEXT: invoke void @_Z8getLargev
+// CHECK-NEXT: to label %[[OUTER_CONT:[^ ]+]] unwind label %[[OUTER_LPAD2:.+]]
+//
+// CHECK: [[OUTER_CONT]]:
+// CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[T_OUTER]])
+// CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[CLEAN]])
+// CHECK: ret void
+//
+// CHECK: [[OUTER_LPAD]]:
+// CHECK-NOT: call void @llvm.lifetime
+// CHECK: br label %[[EHCLEANUP:.+]]
+//
+// CHECK: [[OUTER_LPAD2]]:
+// CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[T_OUTER]])
+// CHECK: br label %[[EHCLEANUP]]
+//
+// CHECK: [[EHCLEANUP]]:
+// CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[CLEAN]])
+
+ NontrivialDtor clean;
+
+ try {
+ getLarge();
+ getLarge();
+ } catch (...) {}
+
+ getLarge();
+}
+
+// CHECK-LABEL: define void @_Z39cleanupInTryHappensBeforeCleanupInCatchv
+void cleanupInTryHappensBeforeCleanupInCatch() {
+// CHECK: %[[T1:[^ ]+]] = bitcast %struct.Large* %{{[^ ]+}} to i8*
+// CHECK: call void @llvm.lifetime.start.p0i8({{[^,]+}}, i8* nonnull %[[T1]])
+// CHECK-NEXT: invoke void @_Z8getLargev
+// CHECK-NEXT: to label %[[CONT:[^ ]+]] unwind label %[[LPAD:[^ ]+]]
+//
+// CHECK: [[CONT]]:
+// CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[T1]])
+// CHECK: br label %[[TRY_CONT]]
+//
+// CHECK: [[LPAD]]:
+// CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[T1]])
+// CHECK: br i1 {{[^,]+}}, label %[[CATCH_INT_MATCH:[^,]+]], label %[[CATCH_ALL:.+]]
+//
+// CHECK: [[CATCH_INT_MATCH]]:
+// CHECK: %[[T2:[^ ]+]] = bitcast %struct.Large* %{{[^ ]+}} to i8*
+// CHECK: call void @llvm.lifetime.start.p0i8({{[^,]+}}, i8* nonnull %[[T2]])
+// CHECK-NEXT: invoke void @_Z8getLargev
+// CHECK-NEXT: to label %[[CATCH_INT_CONT:[^ ]+]] unwind label %[[CATCH_INT_LPAD:[^ ]+]]
+//
+// CHECK: [[CATCH_INT_CONT]]:
+// CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[T2]])
+// CHECK: br label %[[TRY_CONT]]
+//
+// CHECK: [[TRY_CONT]]:
+// CHECK: ret void
+//
+// CHECK: [[CATCH_ALL]]:
+// CHECK: %[[T3:[^ ]+]] = bitcast %struct.Large* %{{[^ ]+}} to i8*
+// CHECK: call void @llvm.lifetime.start.p0i8({{[^,]+}}, i8* nonnull %[[T3]])
+// CHECK-NEXT: invoke void @_Z8getLargev
+// CHECK-NEXT: to label %[[CATCH_ALL_CONT:[^ ]+]] unwind label %[[CATCH_ALL_LPAD:[^ ]+]]
+//
+// CHECK: [[CATCH_ALL_CONT]]:
+// CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[T3]])
+// CHECK: br label %[[TRY_CONT]]
+//
+// CHECK: [[CATCH_ALL_LPAD]]:
+// CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[T3]])
+//
+// CHECK: [[CATCH_INT_LPAD]]:
+// CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[T2]])
+// CHECK-NOT: call void @llvm.lifetime
+
+ try {
+ getLarge();
+ } catch (const int &) {
+ getLarge();
+ } catch (...) {
+ getLarge();
+ }
+}
+
+// FIXME: We don't currently emit lifetime markers for aggregate by-value
+// temporaries (e.g. given a function `Large combine(Large, Large);`
+// combine(getLarge(), getLarge()) "leaks" two `Large`s). We probably should. We
+// also don't emit markers for things like:
+//
+// {
+// Large L = getLarge();
+// combine(L, L);
+// }
+//
+// Though this arguably isn't as bad, since we pass a pointer to `L` as one of
+// the two args.
diff --git a/src/llvm-project/clang/test/CodeGenCXX/stack-reuse-miscompile.cpp b/src/llvm-project/clang/test/CodeGenCXX/stack-reuse-miscompile.cpp
new file mode 100644
index 0000000..4e824d9
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/stack-reuse-miscompile.cpp
@@ -0,0 +1,54 @@
+// RUN: %clang_cc1 -triple armv7l-unknown-linux-gnueabihf -emit-llvm -O1 -disable-llvm-passes -std=c++03 %s -o - | FileCheck %s --implicit-check-not=llvm.lifetime
+
+class S {
+ char *ptr;
+ unsigned int len;
+};
+
+class T {
+ S left;
+ S right;
+
+public:
+ T(const char s[]);
+ T(S);
+
+ T concat(const T &Suffix) const;
+ const char * str() const;
+};
+
+const char * f(S s)
+{
+// It's essential that the lifetimes of all three T temporaries here are
+// overlapping. They must all remain alive through the call to str().
+//
+// CHECK: [[T1:%.*]] = alloca %class.T, align 4
+// CHECK: [[T2:%.*]] = alloca %class.T, align 4
+// CHECK: [[T3:%.*]] = alloca %class.T, align 4
+//
+// FIXME: We could defer starting the lifetime of the return object of concat
+// until the call.
+// CHECK: [[T1i8:%.*]] = bitcast %class.T* [[T1]] to i8*
+// CHECK: call void @llvm.lifetime.start.p0i8(i64 16, i8* [[T1i8]])
+//
+// CHECK: [[T2i8:%.*]] = bitcast %class.T* [[T2]] to i8*
+// CHECK: call void @llvm.lifetime.start.p0i8(i64 16, i8* [[T2i8]])
+// CHECK: [[T4:%.*]] = call %class.T* @_ZN1TC1EPKc(%class.T* [[T2]], i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i32 0, i32 0))
+//
+// CHECK: [[T3i8:%.*]] = bitcast %class.T* [[T3]] to i8*
+// CHECK: call void @llvm.lifetime.start.p0i8(i64 16, i8* [[T3i8]])
+// CHECK: [[T5:%.*]] = call %class.T* @_ZN1TC1E1S(%class.T* [[T3]], [2 x i32] %{{.*}})
+//
+// CHECK: call void @_ZNK1T6concatERKS_(%class.T* sret [[T1]], %class.T* [[T2]], %class.T* dereferenceable(16) [[T3]])
+// CHECK: [[T6:%.*]] = call i8* @_ZNK1T3strEv(%class.T* [[T1]])
+//
+// CHECK: call void @llvm.lifetime.end.p0i8(
+// CHECK: call void @llvm.lifetime.end.p0i8(
+// CHECK: call void @llvm.lifetime.end.p0i8(
+// CHECK: ret i8* [[T6]]
+
+ return T("[").concat(T(s)).str();
+}
+
+// CHECK: declare {{.*}}llvm.lifetime.start
+// CHECK: declare {{.*}}llvm.lifetime.end
diff --git a/src/llvm-project/clang/test/CodeGenCXX/stack-reuse.cpp b/src/llvm-project/clang/test/CodeGenCXX/stack-reuse.cpp
new file mode 100644
index 0000000..8325604
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/stack-reuse.cpp
@@ -0,0 +1,146 @@
+// RUN: %clang_cc1 -triple armv7-unknown-linux-gnueabihf %s -o - -emit-llvm -O1 | FileCheck %s
+
+// Stack should be reused when possible, no need to allocate two separate slots
+// if they have disjoint lifetime.
+
+// Sizes of objects are related to previously existed threshold of 32. In case
+// of S_large stack size is rounded to 40 bytes.
+
+// 32B
+struct S_small {
+ int a[8];
+};
+
+// 36B
+struct S_large {
+ int a[9];
+};
+
+// Helper class for lifetime scope absence testing
+struct Combiner {
+ S_large a, b;
+
+ Combiner(S_large);
+ Combiner f();
+};
+
+extern S_small foo_small();
+extern S_large foo_large();
+extern void bar_small(S_small*);
+extern void bar_large(S_large*);
+
+// Prevent mangling of function names.
+extern "C" {
+
+void small_rvoed_unnamed_temporary_object() {
+// CHECK-LABEL: define void @small_rvoed_unnamed_temporary_object
+// CHECK: call void @llvm.lifetime.start
+// CHECK: call void @_Z9foo_smallv
+// CHECK: call void @llvm.lifetime.end
+// CHECK: call void @llvm.lifetime.start
+// CHECK: call void @_Z9foo_smallv
+// CHECK: call void @llvm.lifetime.end
+
+ foo_small();
+ foo_small();
+}
+
+void large_rvoed_unnamed_temporary_object() {
+// CHECK-LABEL: define void @large_rvoed_unnamed_temporary_object
+// CHECK: call void @llvm.lifetime.start
+// CHECK: call void @_Z9foo_largev
+// CHECK: call void @llvm.lifetime.end
+// CHECK: call void @llvm.lifetime.start
+// CHECK: call void @_Z9foo_largev
+// CHECK: call void @llvm.lifetime.end
+
+ foo_large();
+ foo_large();
+}
+
+void small_rvoed_named_temporary_object() {
+// CHECK-LABEL: define void @small_rvoed_named_temporary_object
+// CHECK: call void @llvm.lifetime.start
+// CHECK: call void @_Z9foo_smallv
+// CHECK: call void @llvm.lifetime.end
+// CHECK: call void @llvm.lifetime.start
+// CHECK: call void @_Z9foo_smallv
+// CHECK: call void @llvm.lifetime.end
+
+ {
+ S_small s = foo_small();
+ }
+ {
+ S_small s = foo_small();
+ }
+}
+
+void large_rvoed_named_temporary_object() {
+// CHECK-LABEL: define void @large_rvoed_named_temporary_object
+// CHECK: call void @llvm.lifetime.start
+// CHECK: call void @_Z9foo_largev
+// CHECK: call void @llvm.lifetime.end
+// CHECK: call void @llvm.lifetime.start
+// CHECK: call void @_Z9foo_largev
+// CHECK: call void @llvm.lifetime.end
+
+ {
+ S_large s = foo_large();
+ }
+ {
+ S_large s = foo_large();
+ }
+}
+
+void small_auto_object() {
+// CHECK-LABEL: define void @small_auto_object
+// CHECK: call void @llvm.lifetime.start
+// CHECK: call void @_Z9bar_smallP7S_small
+// CHECK: call void @llvm.lifetime.end
+// CHECK: call void @llvm.lifetime.start
+// CHECK: call void @_Z9bar_smallP7S_small
+// CHECK: call void @llvm.lifetime.end
+
+ {
+ S_small s;
+ bar_small(&s);
+ }
+ {
+ S_small s;
+ bar_small(&s);
+ }
+}
+
+void large_auto_object() {
+// CHECK-LABEL: define void @large_auto_object
+// CHECK: call void @llvm.lifetime.start
+// CHECK: call void @_Z9bar_largeP7S_large
+// CHECK: call void @llvm.lifetime.end
+// CHECK: call void @llvm.lifetime.start
+// CHECK: call void @_Z9bar_largeP7S_large
+// CHECK: call void @llvm.lifetime.end
+
+ {
+ S_large s;
+ bar_large(&s);
+ }
+ {
+ S_large s;
+ bar_large(&s);
+ }
+}
+
+int large_combiner_test(S_large s) {
+// CHECK-LABEL: define i32 @large_combiner_test
+// CHECK: [[T2:%.*]] = alloca %struct.Combiner
+// CHECK: [[T1:%.*]] = alloca %struct.Combiner
+// CHECK: [[T3:%.*]] = call %struct.Combiner* @_ZN8CombinerC1E7S_large(%struct.Combiner* nonnull [[T1]], [9 x i32] %s.coerce)
+// CHECK: call void @_ZN8Combiner1fEv(%struct.Combiner* nonnull sret [[T2]], %struct.Combiner* nonnull [[T1]])
+// CHECK: [[T4:%.*]] = getelementptr inbounds %struct.Combiner, %struct.Combiner* [[T2]], i32 0, i32 0, i32 0, i32 0
+// CHECK: [[T5:%.*]] = load i32, i32* [[T4]]
+// CHECK: ret i32 [[T5]]
+
+ return Combiner(s).f().a.a[0];
+}
+
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/static-assert.cpp b/src/llvm-project/clang/test/CodeGenCXX/static-assert.cpp
new file mode 100644
index 0000000..ff82f6d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/static-assert.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - -std=c++11 -verify
+// expected-no-diagnostics
+
+static_assert(true, "");
+
+void f() {
+ static_assert(true, "");
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/static-data-member-single-emission.cpp b/src/llvm-project/clang/test/CodeGenCXX/static-data-member-single-emission.cpp
new file mode 100644
index 0000000..8c04fab
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/static-data-member-single-emission.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+
+template <typename T>
+struct HasStaticInit {
+static const int index;
+};
+extern "C"
+int the_count = 0;
+template <typename T>
+const int HasStaticInit<T>::index = the_count++;
+
+template <typename T> int func_tmpl1() { return HasStaticInit<T>::index; }
+template <typename T> int func_tmpl2() { return HasStaticInit<T>::index; }
+template <typename T> int func_tmpl3() { return HasStaticInit<T>::index; }
+void useit() {
+ func_tmpl1<int>();
+ func_tmpl2<int>();
+ func_tmpl3<int>();
+}
+
+// Throw in a final explicit instantiation to see that it doesn't screw things
+// up.
+template struct HasStaticInit<int>;
+
+// There should only be one entry, not 3.
+// CHECK: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }]
+
+// There should only be one update to @the_count.
+// CHECK-NOT: store i32 %{{.*}}, i32* @the_count
+// CHECK: store i32 %{{.*}}, i32* @the_count
+// CHECK-NOT: store i32 %{{.*}}, i32* @the_count
diff --git a/src/llvm-project/clang/test/CodeGenCXX/static-data-member.cpp b/src/llvm-project/clang/test/CodeGenCXX/static-data-member.cpp
new file mode 100644
index 0000000..5ffd83f
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/static-data-member.cpp
@@ -0,0 +1,110 @@
+// RUN: %clang_cc1 -triple x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - %s | \
+// RUN: FileCheck --check-prefix=MACHO %s
+
+// CHECK: @_ZN5test11A1aE = constant i32 10, align 4
+// CHECK: @_ZN5test212_GLOBAL__N_11AIiE1xE = internal global i32 0, align 4
+// CHECK: @_ZN5test31AIiE1xE = weak_odr global i32 0, comdat, align 4
+// CHECK: @_ZGVN5test31AIiE1xE = weak_odr global i64 0, comdat($_ZN5test31AIiE1xE)
+// MACHO: @_ZGVN5test31AIiE1xE = weak_odr global i64 0
+// MACHO-NOT: comdat
+
+// CHECK: _ZN5test51U2k0E = global i32 0
+// CHECK: _ZN5test51U2k1E = global i32 0
+// CHECK: _ZN5test51U2k2E = constant i32 76
+// CHECK-NOT: test51U2k3E
+// CHECK-NOT: test51U2k4E
+
+// PR5564.
+namespace test1 {
+ struct A {
+ static const int a = 10;
+ };
+
+ const int A::a;
+
+ struct S {
+ static int 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-LABEL: 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-LABEL: define internal void @__cxx_global_var_init.1() {{.*}} comdat($_ZN5test31AIiE1xE)
+ // MACHO-LABEL: define internal void @__cxx_global_var_init.1()
+ // MACHO-NOT: comdat
+ // CHECK: [[GUARDBYTE:%.*]] = load i8, 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
+}
+
+// Test that we can fold member lookup expressions which resolve to static data
+// members.
+namespace test4 {
+ struct A {
+ static const int n = 76;
+ };
+
+ int f(A *a) {
+ // CHECK-LABEL: define i32 @_ZN5test41fEPNS_1AE
+ // CHECK: ret i32 76
+ return a->n;
+ }
+}
+
+// Test that static data members in unions behave properly.
+namespace test5 {
+ union U {
+ static int k0;
+ static const int k1;
+ static const int k2 = 76;
+ static const int k3;
+ static const int k4 = 81;
+ };
+ int U::k0;
+ const int U::k1 = (k0 = 9, 42);
+ const int U::k2;
+
+ // CHECK: store i32 9, i32* @_ZN5test51U2k0E
+ // CHECK: store i32 {{.*}}, i32* @_ZN5test51U2k1E
+ // CHECK-NOT: store {{.*}} i32* @_ZN5test51U2k2E
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/static-destructor.cpp b/src/llvm-project/clang/test/CodeGenCXX/static-destructor.cpp
new file mode 100644
index 0000000..0ea84f8
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/static-destructor.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 %s -triple=x86_64-pc-linux -emit-llvm -o - | FileCheck --check-prefix=X86 %s
+// RUN: %clang_cc1 %s -triple=wasm32 -emit-llvm -o - | FileCheck --check-prefix=WASM %s
+// RUN: %clang_cc1 %s -triple=armv7-apple-darwin9 -emit-llvm -o - | FileCheck --check-prefix=ARM %s
+
+// Test that destructors are not passed directly to __cxa_atexit when their
+// signatures do not match the type of its first argument.
+// e.g. ARM and WebAssembly have destructors that return this instead of void.
+
+
+class Foo {
+ public:
+ ~Foo() {
+ }
+};
+
+Foo global;
+
+// X86 destructors have void return, and are registered directly with __cxa_atexit.
+// X86: define internal void @__cxx_global_var_init()
+// X86: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%class.Foo*)* @_ZN3FooD1Ev to void (i8*)*), i8* getelementptr inbounds (%class.Foo, %class.Foo* @global, i32 0, i32 0), i8* @__dso_handle)
+
+// ARM destructors return this, but can be registered directly with __cxa_atexit
+// because the calling conventions tolerate the mismatch.
+// ARM: define internal void @__cxx_global_var_init()
+// ARM: call i32 @__cxa_atexit(void (i8*)* bitcast (%class.Foo* (%class.Foo*)* @_ZN3FooD1Ev to void (i8*)*), i8* getelementptr inbounds (%class.Foo, %class.Foo* @global, i32 0, i32 0), i8* @__dso_handle)
+
+// Wasm destructors return this, and use a wrapper function, which is registered
+// with __cxa_atexit.
+// WASM: define internal void @__cxx_global_var_init()
+// WASM: call i32 @__cxa_atexit(void (i8*)* @__cxx_global_array_dtor, i8* null, i8* @__dso_handle)
+
+// WASM: define internal void @__cxx_global_array_dtor(i8*)
+// WASM: %call = call %class.Foo* @_ZN3FooD1Ev(%class.Foo* @global)
diff --git a/src/llvm-project/clang/test/CodeGenCXX/static-init-1.cpp b/src/llvm-project/clang/test/CodeGenCXX/static-init-1.cpp
new file mode 100644
index 0000000..09bf7bf
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/static-init-1.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -triple=x86_64-apple-darwin9 -emit-llvm %s -o - | FileCheck %s
+
+extern "C" int printf(...);
+
+static int count;
+
+int func2(int c) { return printf("loading the func2(%d)\n", c); };
+int func1(int c) { return printf("loading the func1(%d)\n", c); }
+
+static int loader_1 = func1(++count);
+// CHECK: call i32 @_Z5func1i
+
+int loader_2 = func2(++count);
+
+static int loader_3 = func1(++count);
+// CHECK: call i32 @_Z5func1i
+
+int main() {}
+
+int loader_4 = func2(++count);
+static int loader_5 = func1(++count);
+int loader_6 = func2(++count);
+// CHECK: call i32 @_Z5func1i
+
+// CHECK-NOT: call i32 @_Z5func1i
diff --git a/src/llvm-project/clang/test/CodeGenCXX/static-init-2.cpp b/src/llvm-project/clang/test/CodeGenCXX/static-init-2.cpp
new file mode 100644
index 0000000..354fcd4
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/static-init-2.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -emit-llvm-only -verify %s
+// expected-no-diagnostics
+
+// Make sure we don't crash generating y; its value is constant, but the
+// initializer has side effects, so EmitConstantExpr should fail.
+int x();
+int y = x() & 0;
diff --git a/src/llvm-project/clang/test/CodeGenCXX/static-init-3.cpp b/src/llvm-project/clang/test/CodeGenCXX/static-init-3.cpp
new file mode 100644
index 0000000..083e001
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/static-init-3.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -emit-llvm -triple x86_64-apple-darwin10.0.0 -o - %s | FileCheck %s
+
+// PR7050
+template<class T> struct X0 : public T { };
+
+template <class T>
+struct X1
+{
+ static T & instance;
+ // include this to provoke instantiation at pre-execution time
+ static void use(T const &) {}
+ static T & get() {
+ static X0<T> t;
+ use(instance);
+ return static_cast<T &>(t);
+ }
+};
+
+// CHECK: @_ZN2X1I2X2I1BEE8instanceE = linkonce_odr global %struct.X2* null, align 8
+// CHECJ: @_ZN2X1I2X2I1AEE8instanceE = linkonce_odr global %struct.X2* null, align 8
+template<class T> T & X1<T>::instance = X1<T>::get();
+
+class A { };
+class B : public A { };
+
+template<typename T> struct X2 {};
+X2< B > bg = X1< X2< B > >::get();
+X2< A > ag = X1< X2< A > >::get();
diff --git a/src/llvm-project/clang/test/CodeGenCXX/static-init-4.cpp b/src/llvm-project/clang/test/CodeGenCXX/static-init-4.cpp
new file mode 100644
index 0000000..a4bb987
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/static-init-4.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -std=c++11 -S -emit-llvm -o - %s -triple x86_64-linux-gnu | FileCheck %s
+
+typedef __attribute__((vector_size(4*4))) float float32x4_t;
+union QDSUnion { float32x4_t q; float s[4]; };
+constexpr float32x4_t a = {1,2,3,4};
+QDSUnion t = {{(a)}};
+// CHECK: @t = global %union.QDSUnion { <4 x float> <float 1.000000e+00, float 2.000000e+00, float 3.000000e+00, float 4.000000e+00> }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/static-init-pnacl.cpp b/src/llvm-project/clang/test/CodeGenCXX/static-init-pnacl.cpp
new file mode 100644
index 0000000..ba06420
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/static-init-pnacl.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -emit-llvm -triple=le32-unknown-nacl -o - %s | FileCheck %s
+
+int f();
+
+// Test that PNaCl uses the Itanium/x86 ABI in which the static
+// variable's guard variable is tested via "load i8 and compare with
+// zero" rather than the ARM ABI which uses "load i32 and test the
+// bottom bit".
+void g() {
+ static int a = f();
+}
+// CHECK: [[LOAD:%.*]] = load atomic i8, i8* bitcast (i64* @_ZGVZ1gvE1a to i8*) acquire
+// CHECK-NEXT: [[GUARD:%.*]] = icmp eq i8 [[LOAD]], 0
+// CHECK-NEXT: br i1 [[GUARD]]
diff --git a/src/llvm-project/clang/test/CodeGenCXX/static-init-wasm.cpp b/src/llvm-project/clang/test/CodeGenCXX/static-init-wasm.cpp
new file mode 100644
index 0000000..579818c
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/static-init-wasm.cpp
@@ -0,0 +1,54 @@
+// RUN: %clang_cc1 -emit-llvm -triple=wasm32-unknown-unknown -o - %s \
+// RUN: | FileCheck %s -check-prefix=WEBASSEMBLY32
+// RUN: %clang_cc1 -emit-llvm -triple=wasm64-unknown-unknown -o - %s \
+// RUN: | FileCheck %s -check-prefix=WEBASSEMBLY64
+
+// Test that we don't create common blocks.
+int tentative;
+// WEBASSEMBLY32: @tentative = global i32 0, align 4
+// WEBASSEMBLY64: @tentative = global i32 0, align 4
+
+// Test that WebAssembly uses the ARM-style ABI in which the static
+// variable's guard variable is tested via "load i8 and test the
+// bottom bit" rather than the Itanium/x86 ABI which uses "load i8
+// and compare with zero".
+int f();
+void g() {
+ static int a = f();
+}
+// WEBASSEMBLY32-LABEL: @_Z1gv()
+// WEBASSEMBLY32: %[[R0:.+]] = load atomic i8, i8* bitcast (i32* @_ZGVZ1gvE1a to i8*) acquire, align 4
+// WEBASSEMBLY32-NEXT: %[[R1:.+]] = and i8 %[[R0]], 1
+// WEBASSEMBLY32-NEXT: %[[R2:.+]] = icmp eq i8 %[[R1]], 0
+// WEBASSEMBLY32-NEXT: br i1 %[[R2]], label %[[CHECK:.+]], label %[[END:.+]],
+// WEBASSEMBLY32: [[CHECK]]
+// WEBASSEMBLY32: call i32 @__cxa_guard_acquire
+// WEBASSEMBLY32: [[END]]
+// WEBASSEMBLY32: call void @__cxa_guard_release
+//
+// WEBASSEMBLY64-LABEL: @_Z1gv()
+// WEBASSEMBLY64: %[[R0:.+]] = load atomic i8, i8* bitcast (i64* @_ZGVZ1gvE1a to i8*) acquire, align 8
+// WEBASSEMBLY64-NEXT: %[[R1:.+]] = and i8 %[[R0]], 1
+// WEBASSEMBLY64-NEXT: %[[R2:.+]] = icmp eq i8 %[[R1]], 0
+// WEBASSEMBLY64-NEXT: br i1 %[[R2]], label %[[CHECK:.+]], label %[[END:.+]],
+// WEBASSEMBLY64: [[CHECK]]
+// WEBASSEMBLY64: call i32 @__cxa_guard_acquire
+// WEBASSEMBLY64: [[END]]
+// WEBASSEMBLY64: call void @__cxa_guard_release
+
+// Test various aspects of static constructor calls.
+struct A {
+ A();
+};
+
+A theA;
+
+// WEBASSEMBLY32: define internal void @__cxx_global_var_init() #3 {
+// WEBASSEMBLY32: call %struct.A* @_ZN1AC1Ev(%struct.A* @theA)
+// WEBASSEMBLY32: define internal void @_GLOBAL__sub_I_static_init_wasm.cpp() #3 {
+// WEBASSEMBLY32: call void @__cxx_global_var_init()
+//
+// WEBASSEMBLY64: define internal void @__cxx_global_var_init() #3 {
+// WEBASSEMBLY64: call %struct.A* @_ZN1AC1Ev(%struct.A* @theA)
+// WEBASSEMBLY64: define internal void @_GLOBAL__sub_I_static_init_wasm.cpp() #3 {
+// WEBASSEMBLY64: call void @__cxx_global_var_init()
diff --git a/src/llvm-project/clang/test/CodeGenCXX/static-init.cpp b/src/llvm-project/clang/test/CodeGenCXX/static-init.cpp
new file mode 100644
index 0000000..925ddec
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/static-init.cpp
@@ -0,0 +1,175 @@
+// RUN: %clang_cc1 %s -triple=x86_64-pc-linuxs -emit-llvm -std=c++98 -o - | FileCheck -check-prefix=CHECK -check-prefix=CHECK98 %s
+// RUN: %clang_cc1 %s -triple=x86_64-pc-linuxs -emit-llvm -std=c++11 -o - | FileCheck -check-prefix=CHECK -check-prefix=CHECK11 %s
+
+// CHECK: @_ZZ1hvE1i = internal global i32 0, align 4
+// CHECK: @base_req = global [4 x i8] c"foo\00", align 1
+// CHECK: @base_req_uchar = global [4 x i8] c"bar\00", align 1
+
+// CHECK: @_ZZN5test31BC1EvE1u = internal global { i8, [3 x i8] } { i8 97, [3 x i8] undef }, align 4
+
+// CHECK: @_ZZ2h2vE1i = linkonce_odr global i32 0, comdat, align 4
+// CHECK: @_ZGVZ2h2vE1i = linkonce_odr global i64 0, comdat, align 8{{$}}
+// CHECK: @_ZZN5test1L6getvarEiE3var = internal constant [4 x i32] [i32 1, i32 0, i32 2, i32 4], align 16
+// CHECK98: @_ZZN5test414useStaticLocalEvE3obj = linkonce_odr global %"struct.test4::HasVTable" zeroinitializer, comdat, align 8
+// CHECK11: @_ZZN5test414useStaticLocalEvE3obj = linkonce_odr global { i8** } { i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN5test49HasVTableE, i32 0, inrange i32 0, i32 2) }, comdat, align 8
+
+struct A {
+ A();
+ ~A();
+};
+
+void f() {
+ // CHECK: load atomic i8, i8* bitcast (i64* @_ZGVZ1fvE1a to i8*) acquire, align 8
+ // CHECK: call i32 @__cxa_guard_acquire
+ // CHECK: call void @_ZN1AC1Ev
+ // CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.A*)* @_ZN1AD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.A, %struct.A* @_ZZ1fvE1a, i32 0, i32 0), i8* @__dso_handle)
+ // CHECK: call void @__cxa_guard_release
+ static A a;
+}
+
+void g() {
+ // CHECK: call i8* @_Znwm(i64 1)
+ // CHECK: call void @_ZN1AC1Ev(
+ static A& a = *new A;
+}
+
+int a();
+void h() {
+ static const int i = a();
+}
+
+// CHECK: define linkonce_odr void @_Z2h2v() {{.*}} comdat {
+inline void h2() {
+ static int i = a();
+}
+
+void h3() {
+ h2();
+}
+
+// PR6980: this shouldn't crash
+namespace test0 {
+ struct A { A(); };
+ __attribute__((noreturn)) int throw_exception();
+
+ void test() {
+ throw_exception();
+ static A r;
+ }
+}
+
+namespace test1 {
+ // CHECK-LABEL: define internal i32 @_ZN5test1L6getvarEi(
+ static inline int getvar(int index) {
+ static const int var[] = { 1, 0, 2, 4 };
+ return var[index];
+ }
+
+ void test() { (void) getvar(2); }
+}
+
+// Make sure we emit the initializer correctly for the following:
+char base_req[] = { "foo" };
+unsigned char base_req_uchar[] = { "bar" };
+
+namespace union_static_local {
+ // CHECK-LABEL: define internal void @_ZZN18union_static_local4testEvEN1c4mainEv
+ // CHECK: call void @_ZN18union_static_local1fEPNS_1xE(%"union.union_static_local::x"* bitcast ({ [2 x i8*] }* @_ZZN18union_static_local4testEvE3foo to %"union.union_static_local::x"*))
+ union x { long double y; const char *x[2]; };
+ void f(union x*);
+ void test() {
+ static union x foo = { .x = { "a", "b" } };
+ struct c {
+ static void main() {
+ f(&foo);
+ }
+ };
+ c::main();
+ }
+}
+
+// rdar://problem/11091093
+// Static variables should be consistent across constructor
+// or destructor variants.
+namespace test2 {
+ struct A {
+ A();
+ ~A();
+ };
+
+ struct B : virtual A {
+ B();
+ ~B();
+ };
+
+ // If we ever implement this as a delegate ctor call, just change
+ // this to take variadic arguments or something.
+ extern int foo();
+ B::B() {
+ static int x = foo();
+ }
+ // CHECK-LABEL: define void @_ZN5test21BC2Ev
+ // CHECK: load atomic i8, i8* bitcast (i64* @_ZGVZN5test21BC1EvE1x to i8*) acquire,
+ // CHECK: call i32 @__cxa_guard_acquire(i64* @_ZGVZN5test21BC1EvE1x)
+ // CHECK: [[T0:%.*]] = call i32 @_ZN5test23fooEv()
+ // CHECK: store i32 [[T0]], i32* @_ZZN5test21BC1EvE1x,
+ // CHECK: call void @__cxa_guard_release(i64* @_ZGVZN5test21BC1EvE1x)
+
+ // CHECK-LABEL: define void @_ZN5test21BC1Ev
+ // CHECK: load atomic i8, i8* bitcast (i64* @_ZGVZN5test21BC1EvE1x to i8*) acquire,
+ // CHECK: call i32 @__cxa_guard_acquire(i64* @_ZGVZN5test21BC1EvE1x)
+ // CHECK: [[T0:%.*]] = call i32 @_ZN5test23fooEv()
+ // CHECK: store i32 [[T0]], i32* @_ZZN5test21BC1EvE1x,
+ // CHECK: call void @__cxa_guard_release(i64* @_ZGVZN5test21BC1EvE1x)
+
+ // This is just for completeness, because we actually emit this
+ // using a delegate dtor call.
+ B::~B() {
+ static int y = foo();
+ }
+ // CHECK-LABEL: define void @_ZN5test21BD2Ev(
+ // CHECK: load atomic i8, i8* bitcast (i64* @_ZGVZN5test21BD1EvE1y to i8*) acquire,
+ // CHECK: call i32 @__cxa_guard_acquire(i64* @_ZGVZN5test21BD1EvE1y)
+ // CHECK: [[T0:%.*]] = call i32 @_ZN5test23fooEv()
+ // CHECK: store i32 [[T0]], i32* @_ZZN5test21BD1EvE1y,
+ // CHECK: call void @__cxa_guard_release(i64* @_ZGVZN5test21BD1EvE1y)
+
+ // CHECK-LABEL: define void @_ZN5test21BD1Ev(
+ // CHECK: call void @_ZN5test21BD2Ev(
+}
+
+// This shouldn't error out.
+namespace test3 {
+ struct A {
+ A();
+ ~A();
+ };
+
+ struct B : virtual A {
+ B();
+ ~B();
+ };
+
+ B::B() {
+ union U { char x; int i; };
+ static U u = { 'a' };
+ }
+ // CHECK-LABEL: define void @_ZN5test31BC2Ev(
+ // CHECK-LABEL: define void @_ZN5test31BC1Ev(
+}
+
+// We forgot to set the comdat when replacing the global with a different type.
+namespace test4 {
+struct HasVTable {
+ virtual void f();
+};
+inline HasVTable &useStaticLocal() {
+ static HasVTable obj;
+ return obj;
+}
+void useit() {
+ useStaticLocal();
+}
+// CHECK: define linkonce_odr dereferenceable(8) %"struct.test4::HasVTable"* @_ZN5test414useStaticLocalEv()
+// CHECK: ret %"struct.test4::HasVTable"*{{.*}} @_ZZN5test414useStaticLocalEvE3obj
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/static-initializer-branch-weights.cpp b/src/llvm-project/clang/test/CodeGenCXX/static-initializer-branch-weights.cpp
new file mode 100644
index 0000000..f9e7781
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/static-initializer-branch-weights.cpp
@@ -0,0 +1,126 @@
+// RUN: %clang_cc1 -emit-llvm -std=c++1z %s -o - -triple=x86_64-linux-gnu | FileCheck %s
+
+struct S { S(); ~S(); };
+
+// CHECK-LABEL: define {{.*}}global_var_init
+// CHECK-NOT: br
+// CHECK: call void @_ZN1SC1Ev({{.*}}* @global)
+S global;
+
+// CHECK-LABEL: define {{.*}}global_var_init
+// FIXME: Do we really need thread-safe initialization here? We don't run
+// global ctors on multiple threads. (If we were to do so, we'd need thread-safe
+// init for B<int>::member and B<int>::inline_member too.)
+// CHECK: load atomic i8, i8* bitcast (i64* @_ZGV13inline_global to i8*) acquire,
+// CHECK: icmp eq i8 {{.*}}, 0
+// CHECK: br i1
+// CHECK-NOT: !prof
+// CHECK: call void @_ZN1SC1Ev({{.*}}* @inline_global)
+inline S inline_global;
+
+// CHECK-LABEL: define {{.*}}global_var_init
+// CHECK-NOT: br
+// CHECK: call void @_ZN1SC1Ev({{.*}}* @thread_local_global)
+thread_local S thread_local_global;
+
+// CHECK-LABEL: define {{.*}}global_var_init
+// CHECK: load i8, i8* bitcast (i64* @_ZGV26thread_local_inline_global to i8*)
+// CHECK: icmp eq i8 {{.*}}, 0
+// CHECK: br i1
+// CHECK-NOT: !prof
+// CHECK: call void @_ZN1SC1Ev({{.*}}* @thread_local_inline_global)
+thread_local inline S thread_local_inline_global;
+
+struct A {
+ static S member;
+ static thread_local S thread_local_member;
+
+ // CHECK-LABEL: define {{.*}}global_var_init
+ // CHECK: load atomic i8, i8* bitcast (i64* @_ZGVN1A13inline_memberE to i8*) acquire,
+ // CHECK: icmp eq i8 {{.*}}, 0
+ // CHECK: br i1
+ // CHECK-NOT: !prof
+ // CHECK: call void @_ZN1SC1Ev({{.*}}* @_ZN1A13inline_memberE)
+ static inline S inline_member;
+
+ // CHECK-LABEL: define {{.*}}global_var_init
+ // CHECK: load i8, i8* bitcast (i64* @_ZGVN1A26thread_local_inline_memberE to i8*)
+ // CHECK: icmp eq i8 {{.*}}, 0
+ // CHECK: br i1
+ // CHECK-NOT: !prof
+ // CHECK: call void @_ZN1SC1Ev({{.*}}* @_ZN1A26thread_local_inline_memberE)
+ static thread_local inline S thread_local_inline_member;
+};
+
+// CHECK-LABEL: define void @_Z1fv()
+void f() {
+ // CHECK: load atomic i8, i8* bitcast (i64* @_ZGVZ1fvE12static_local to i8*) acquire,
+ // CHECK: icmp eq i8 {{.*}}, 0
+ // CHECK: br i1 {{.*}}, !prof ![[WEIGHTS_LOCAL:[0-9]*]]
+ static S static_local;
+
+ // CHECK: load i8, i8* @_ZGVZ1fvE19static_thread_local,
+ // CHECK: icmp eq i8 {{.*}}, 0
+ // CHECK: br i1 {{.*}}, !prof ![[WEIGHTS_THREAD_LOCAL:[0-9]*]]
+ static thread_local S static_thread_local;
+}
+
+// CHECK-LABEL: define {{.*}}global_var_init
+// CHECK-NOT: br
+// CHECK: call void @_ZN1SC1Ev({{.*}}* @_ZN1A6memberE)
+S A::member;
+
+// CHECK-LABEL: define {{.*}}global_var_init
+// CHECK-NOT: br
+// CHECK: call void @_ZN1SC1Ev({{.*}}* @_ZN1A19thread_local_memberE)
+thread_local S A::thread_local_member;
+
+template <typename T> struct B {
+ // CHECK-LABEL: define {{.*}}global_var_init
+ // CHECK: load i8, i8* bitcast (i64* @_ZGVN1BIiE6memberE to i8*)
+ // CHECK: icmp eq i8 {{.*}}, 0
+ // CHECK: br i1
+ // CHECK-NOT: !prof
+ // CHECK: call void @_ZN1SC1Ev({{.*}}* @_ZN1BIiE6memberE)
+ static S member;
+
+ // CHECK-LABEL: define {{.*}}global_var_init
+ // CHECK: load i8, i8* bitcast (i64* @_ZGVN1BIiE13inline_memberE to i8*)
+ // CHECK: icmp eq i8 {{.*}}, 0
+ // CHECK: br i1
+ // CHECK-NOT: !prof
+ // CHECK: call void @_ZN1SC1Ev({{.*}}* @_ZN1BIiE13inline_memberE)
+ static inline S inline_member;
+
+ // CHECK-LABEL: define {{.*}}global_var_init
+ // CHECK: load i8, i8* bitcast (i64* @_ZGVN1BIiE19thread_local_memberE to i8*)
+ // CHECK: icmp eq i8 {{.*}}, 0
+ // CHECK: br i1
+ // CHECK-NOT: !prof
+ // CHECK: call void @_ZN1SC1Ev({{.*}}* @_ZN1BIiE19thread_local_memberE)
+ static thread_local S thread_local_member;
+
+ // CHECK-LABEL: define {{.*}}global_var_init
+ // CHECK: load i8, i8* bitcast (i64* @_ZGVN1BIiE26thread_local_inline_memberE to i8*)
+ // CHECK: icmp eq i8 {{.*}}, 0
+ // CHECK: br i1
+ // CHECK-NOT: !prof
+ // CHECK: call void @_ZN1SC1Ev({{.*}}* @_ZN1BIiE26thread_local_inline_memberE)
+ static thread_local inline S thread_local_inline_member;
+};
+template<typename T> S B<T>::member;
+template<typename T> thread_local S B<T>::thread_local_member;
+
+template<typename ...T> void use(T &...);
+void use_b() {
+ use(B<int>::member, B<int>::inline_member, B<int>::thread_local_member,
+ B<int>::thread_local_inline_member);
+}
+
+// CHECK-LABEL: define {{.*}}tls_init()
+// CHECK: load i8, i8* @__tls_guard, align 1
+// CHECK: icmp eq i8 {{.*}}, 0
+// CHECK: br i1 {{.*}}, !prof ![[WEIGHTS_THREAD_LOCAL]]
+
+// CHECK-DAG: ![[WEIGHTS_THREAD_LOCAL]] = !{!"branch_weights", i32 1, i32 1023}
+// CHECK-DAG: ![[WEIGHTS_LOCAL]] = !{!"branch_weights", i32 1, i32 1048575}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/static-local-in-local-class.cpp b/src/llvm-project/clang/test/CodeGenCXX/static-local-in-local-class.cpp
new file mode 100644
index 0000000..a70afcd
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/static-local-in-local-class.cpp
@@ -0,0 +1,160 @@
+// RUN: %clang_cc1 -triple x86_64-linux -fblocks -emit-llvm -o - %s -std=c++1y | FileCheck %s
+
+// CHECK: @"_ZZZNK17pr18020_constexpr3$_1clEvENKUlvE_clEvE2l2" =
+// CHECK: internal global i32* @"_ZZNK17pr18020_constexpr3$_1clEvE2l1"
+// CHECK: @_ZZL14deduced_returnvE1n = internal global i32 42
+// CHECK: @_ZZZL20block_deduced_returnvEUb_E1n = internal global i32 42
+// CHECK: @_ZZ18static_local_labelPvE1q = linkonce_odr global i8* blockaddress(@_Z18static_local_labelPv, %{{.*}})
+// CHECK: @"_ZZNK3$_2clEvE1x" = internal global i32 42
+
+namespace pr6769 {
+struct X {
+ static void f();
+};
+
+void X::f() {
+ static int *i;
+ {
+ struct Y {
+ static void g() {
+ i = new int();
+ *i = 100;
+ (*i) = (*i) +1;
+ }
+ };
+ (void)Y::g();
+ }
+ (void)i;
+}
+}
+
+namespace pr7101 {
+void foo() {
+ static int n = 0;
+ struct Helper {
+ static void Execute() {
+ n++;
+ }
+ };
+ Helper::Execute();
+}
+}
+
+// These tests all break the assumption that the static var decl has to be
+// emitted before use of the var decl. This happens because we defer emission
+// of variables with internal linkage and no initialization side effects, such
+// as 'x'. Then we hit operator()() in 'f', and emit the callee before we emit
+// the arguments, so we emit the innermost function first.
+
+namespace pr18020_lambda {
+// Referring to l1 before emitting it used to crash.
+auto x = []() {
+ static int l1 = 0;
+ return [] { return l1; };
+};
+int f() { return x()(); }
+}
+
+// CHECK-LABEL: define internal i32 @"_ZZNK14pr18020_lambda3$_0clEvENKUlvE_clEv"
+// CHECK: load i32, i32* @"_ZZNK14pr18020_lambda3$_0clEvE2l1"
+
+namespace pr18020_constexpr {
+// Taking the address of l1 in a constant expression used to crash.
+auto x = []() {
+ static int l1 = 0;
+ return [] {
+ static int *l2 = &l1;
+ return *l2;
+ };
+};
+int f() { return x()(); }
+}
+
+// CHECK-LABEL: define internal i32 @"_ZZNK17pr18020_constexpr3$_1clEvENKUlvE_clEv"
+// CHECK: load i32*, i32** @"_ZZZNK17pr18020_constexpr3$_1clEvENKUlvE_clEvE2l2"
+
+// Lambda-less reduction that references l1 before emitting it. This didn't
+// crash if you put it in a namespace.
+struct pr18020_class {
+ auto operator()() {
+ static int l1 = 0;
+ struct U {
+ int operator()() { return l1; }
+ };
+ return U();
+ }
+};
+static pr18020_class x;
+int pr18020_f() { return x()(); }
+
+// CHECK-LABEL: define linkonce_odr i32 @_ZZN13pr18020_classclEvEN1UclEv
+// CHECK: load i32, i32* @_ZZN13pr18020_classclEvE2l1
+
+// In this test case, the function containing the static local will not be
+// emitted because it is unneeded. However, the operator call of the inner class
+// is called, and the static local is referenced and must be emitted.
+static auto deduced_return() {
+ static int n = 42;
+ struct S { int *operator()() { return &n; } };
+ return S();
+}
+extern "C" int call_deduced_return_operator() {
+ return *decltype(deduced_return())()();
+}
+
+// CHECK-LABEL: define i32 @call_deduced_return_operator()
+// CHECK: call i32* @_ZZL14deduced_returnvEN1SclEv(
+// CHECK: load i32, i32* %
+// CHECK: ret i32 %
+
+// CHECK-LABEL: define internal i32* @_ZZL14deduced_returnvEN1SclEv(%struct.S* %this)
+// CHECK: ret i32* @_ZZL14deduced_returnvE1n
+
+static auto block_deduced_return() {
+ auto (^b)() = ^() {
+ static int n = 42;
+ struct S { int *operator()() { return &n; } };
+ return S();
+ };
+ return b();
+}
+extern "C" int call_block_deduced_return() {
+ return *decltype(block_deduced_return())()();
+}
+
+// CHECK-LABEL: define i32 @call_block_deduced_return()
+// CHECK: call i32* @_ZZZL20block_deduced_returnvEUb_EN1SclEv(
+// CHECK: load i32, i32* %
+// CHECK: ret i32 %
+
+// CHECK-LABEL: define internal i32* @_ZZZL20block_deduced_returnvEUb_EN1SclEv(%struct.S.6* %this) #0 align 2 {
+// CHECK: ret i32* @_ZZZL20block_deduced_returnvEUb_E1n
+
+inline auto static_local_label(void *p) {
+ if (p)
+ goto *p;
+ static void *q = &&label;
+ struct S { static void *get() { return q; } };
+ return S();
+label:
+ __builtin_abort();
+}
+void *global_label = decltype(static_local_label(0))::get();
+
+// CHECK-LABEL: define linkonce_odr i8* @_ZZ18static_local_labelPvEN1S3getEv()
+// CHECK: %[[lbl:[^ ]*]] = load i8*, i8** @_ZZ18static_local_labelPvE1q
+// CHECK: ret i8* %[[lbl]]
+
+auto global_lambda = []() {
+ static int x = 42;
+ struct S { static int *get() { return &x; } };
+ return S();
+};
+extern "C" int use_global_lambda() {
+ return *decltype(global_lambda())::get();
+}
+// CHECK-LABEL: define i32 @use_global_lambda()
+// CHECK: call i32* @"_ZZNK3$_2clEvEN1S3getEv"()
+
+// CHECK-LABEL: define internal i32* @"_ZZNK3$_2clEvEN1S3getEv"()
+// CHECK: ret i32* @"_ZZNK3$_2clEvE1x"
diff --git a/src/llvm-project/clang/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp b/src/llvm-project/clang/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp
new file mode 100644
index 0000000..20b409c
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp
@@ -0,0 +1,125 @@
+// RUN: %clang_cc1 %s -std=c++1y -triple=x86_64-pc-linux -emit-llvm -o - | FileCheck --check-prefix=ELF --check-prefix=ALL %s
+// RUN: %clang_cc1 %s -std=c++1y -triple=x86_64-apple-darwin -emit-llvm -o - | FileCheck --check-prefix=MACHO --check-prefix=ALL %s
+
+// ALL: ; ModuleID
+
+extern "C" int foo();
+
+template<typename T> struct A { static int a; };
+template<typename T> int A<T>::a = foo();
+
+// ALLK-NOT: @_ZN1AIcE1aE
+template<> int A<char>::a;
+
+// ALL: @_ZN1AIbE1aE = global i32 10
+template<> int A<bool>::a = 10;
+
+// ALL: @llvm.global_ctors = appending global [8 x { i32, void ()*, i8* }]
+
+// ELF: [{ i32, void ()*, i8* } { i32 65535, void ()* @[[unordered1:[^,]*]], i8* bitcast (i32* @_ZN1AIsE1aE to i8*) },
+// MACHO: [{ i32, void ()*, i8* } { i32 65535, void ()* @[[unordered1:[^,]*]], i8* null },
+
+// ELF: { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered2:[^,]*]], i8* bitcast (i16* @_Z1xIsE to i8*) },
+// MACHO: { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered2:[^,]*]], i8* null },
+
+// ELF: { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered3:[^,]*]], i8* bitcast (i32* @_ZN2ns1aIiE1iE to i8*) },
+// MACHO: { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered3:[^,]*]], i8* null },
+
+// ELF: { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered4:[^,]*]], i8* bitcast (i32* @_ZN2ns1b1iIiEE to i8*) },
+// MACHO: { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered4:[^,]*]], i8* null },
+
+// ELF: { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered5:[^,]*]], i8* bitcast (i32* @_ZN1AIvE1aE to i8*) },
+// MACHO: { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered5:[^,]*]], i8* null },
+
+// ELF: { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered6:[^,]*]], i8* @_Z1xIcE },
+// MACHO: { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered6:[^,]*]], i8* null },
+
+// ALL: { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered7:[^,]*]], i8* null },
+
+// ALL: { i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_static_member_variable_explicit_specialization.cpp, i8* null }]
+
+template int A<short>::a; // Unordered
+int b = foo();
+int c = foo();
+int d = A<void>::a; // Unordered
+
+// An explicit specialization is ordered, and goes in __GLOBAL_sub_I_static_member_variable_explicit_specialization.cpp.
+template<> struct A<int> { static int a; };
+int A<int>::a = foo();
+
+template<typename T> struct S { static T x; static T y; };
+template<> int S<int>::x = foo();
+template<> int S<int>::y = S<int>::x;
+
+template<typename T> T x = foo();
+template short x<short>; // Unordered
+template<> int x<int> = foo();
+int e = x<char>; // Unordered
+
+namespace ns {
+template <typename T> struct a {
+ static int i;
+};
+template<typename T> int a<T>::i = foo();
+template struct a<int>;
+
+struct b {
+ template <typename T> static T i;
+};
+template<typename T> T b::i = foo();
+template int b::i<int>;
+}
+
+namespace {
+template<typename T> struct Internal { static int a; };
+template<typename T> int Internal<T>::a = foo();
+}
+int *use_internal_a = &Internal<int>::a;
+
+// ALL: define internal void @[[unordered1]](
+// ALL: call i32 @foo()
+// ALL: store {{.*}} @_ZN1AIsE1aE
+// ALL: ret
+
+// ALL: define internal void @[[unordered2]](
+// ALL: call i32 @foo()
+// ALL: store {{.*}} @_Z1xIsE
+// ALL: ret
+
+// ALL: define internal void @[[unordered3]](
+// ALL: call i32 @foo()
+// ALL: store {{.*}} @_ZN2ns1aIiE1iE
+// ALL: ret
+
+// ALL: define internal void @[[unordered4]](
+// ALL: call i32 @foo()
+// ALL: store {{.*}} @_ZN2ns1b1iIiEE
+// ALL: ret
+
+// ALL: define internal void @[[unordered5]](
+// ALL: call i32 @foo()
+// ALL: store {{.*}} @_ZN1AIvE1aE
+// ALL: ret
+
+// ALL: define internal void @[[unordered6]](
+// ALL: call i32 @foo()
+// ALL: store {{.*}} @_Z1xIcE
+// ALL: ret
+
+// ALL: define internal void @[[unordered7]](
+// ALL: call i32 @foo()
+// ALL: store {{.*}} @_ZN12_GLOBAL__N_18InternalIiE1aE
+// ALL: ret
+
+// ALL: define internal void @_GLOBAL__sub_I_static_member_variable_explicit_specialization.cpp()
+// We call unique stubs for every ordered dynamic initializer in the TU.
+// ALL: call
+// ALL: call
+// ALL: call
+// ALL: call
+// ALL: call
+// ALL: call
+// ALL: call
+// ALL: call
+// ALL-NOT: call
+// ALL: ret
diff --git a/src/llvm-project/clang/test/CodeGenCXX/static-mutable.cpp b/src/llvm-project/clang/test/CodeGenCXX/static-mutable.cpp
new file mode 100644
index 0000000..6d51f24
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/static-mutable.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 %s -triple=i686-linux-gnu -emit-llvm -o - | FileCheck %s
+
+struct S {
+ mutable int n;
+};
+int f() {
+ // The purpose of this test is to ensure that this variable is a global
+ // not a constant.
+ // CHECK: @_ZZ1fvE1s = internal global {{.*}} { i32 12 }
+ static const S s = { 12 };
+ return ++s.n;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/std-byte.cpp b/src/llvm-project/clang/test/CodeGenCXX/std-byte.cpp
new file mode 100644
index 0000000..a3cc634
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/std-byte.cpp
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -std=c++1z -Werror -triple i386-unknown-unknown -emit-llvm -O1 -disable-llvm-passes -o - %s | FileCheck %s
+
+// std::byte should be considered equivalent to char for aliasing.
+
+namespace std {
+enum byte : unsigned char {};
+}
+
+// CHECK-LABEL: define void @test0(
+extern "C" void test0(std::byte *sb, int *i) {
+ // CHECK: store i8 0, i8* %{{.*}} !tbaa [[TAG_CHAR:!.*]]
+ *sb = std::byte{0};
+
+ // CHECK: store i32 1, i32* %{{.*}} !tbaa [[TAG_INT:!.*]]
+ *i = 1;
+}
+
+enum byte : unsigned char {};
+namespace my {
+enum byte : unsigned char {};
+namespace std {
+enum byte : unsigned char {};
+} // namespace std
+} // namespace my
+
+// Make sure we don't get confused with other enums named 'byte'.
+
+// CHECK-LABEL: define void @test1(
+extern "C" void test1(::byte *b, ::my::byte *mb, ::my::std::byte *msb) {
+ *b = ::byte{0};
+ *mb = ::my::byte{0};
+ *msb = ::my::std::byte{0};
+ // CHECK-NOT: store i8 0, i8* %{{.*}} !tbaa [[TAG_CHAR]]
+}
+
+// CHECK: !"any pointer", [[TYPE_CHAR:!.*]],
+// CHECK: [[TYPE_CHAR]] = !{!"omnipotent char", [[TAG_CXX_TBAA:!.*]],
+// CHECK: [[TAG_CXX_TBAA]] = !{!"Simple C++ TBAA"}
+// CHECK: [[TAG_CHAR]] = !{[[TYPE_CHAR:!.*]], [[TYPE_CHAR]], i64 0}
+// CHECK: [[TAG_INT]] = !{[[TYPE_INT:!.*]], [[TYPE_INT]], i64 0}
+// CHECK: [[TYPE_INT]] = !{!"int", [[TYPE_CHAR]]
diff --git a/src/llvm-project/clang/test/CodeGenCXX/stmtexpr.cpp b/src/llvm-project/clang/test/CodeGenCXX/stmtexpr.cpp
new file mode 100644
index 0000000..4586a3c
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/stmtexpr.cpp
@@ -0,0 +1,192 @@
+// RUN: %clang_cc1 -Wno-unused-value -triple i686-linux-gnu -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 {{.*}} @_ZN1AC1Ei
+// CHECK: call {{.*}} @_ZN1AC1ERKS_
+// CHECK: call {{.*}} @_ZN1AD1Ev
+// CHECK: call {{.*}} @_ZN1BC1ERK1A
+// CHECK: call {{.*}} @_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; }));
+}
+
+// <rdar://problem/14074868>
+// Make sure this doesn't crash.
+int foo5(bool b) {
+ int y = 0;
+ y = ({ A a(1); if (b) goto G; a.i; });
+ G: return y;
+}
+
+// When we emit a full expression with cleanups that contains branches out of
+// the full expression, the result of the inner expression (the call to
+// call_with_cleanups in this case) may not dominate the fallthrough destination
+// of the shared cleanup block.
+//
+// In this case the CFG will be a sequence of two diamonds, but the only
+// dynamically possible execution paths are both left hand branches and both
+// right hand branches. The first diamond LHS will call bar, and the second
+// diamond LHS will assign the result to v, but the call to bar does not
+// dominate the assignment.
+int bar(A, int);
+extern "C" int cleanup_exit_scalar(bool b) {
+ int v = bar(A(1), ({ if (b) return 42; 13; }));
+ return v;
+}
+
+// CHECK-LABEL: define{{.*}} i32 @cleanup_exit_scalar({{.*}})
+// CHECK: call {{.*}} @_ZN1AC1Ei
+// Spill after bar.
+// CHECK: %[[v:[^ ]*]] = call{{.*}} i32 @_Z3bar1Ai({{.*}})
+// CHECK-NEXT: store i32 %[[v]], i32* %[[tmp:[^, ]*]]
+// Do cleanup.
+// CHECK: call {{.*}} @_ZN1AD1Ev
+// CHECK: switch
+// Reload before v assignment.
+// CHECK: %[[v:[^ ]*]] = load i32, i32* %[[tmp]]
+// CHECK-NEXT: store i32 %[[v]], i32* %v
+
+// No need to spill when the expression result is a constant, constants don't
+// have dominance problems.
+extern "C" int cleanup_exit_scalar_constant(bool b) {
+ int v = (A(1), (void)({ if (b) return 42; 0; }), 13);
+ return v;
+}
+
+// CHECK-LABEL: define{{.*}} i32 @cleanup_exit_scalar_constant({{.*}})
+// CHECK: store i32 13, i32* %v
+
+// Check for the same bug for lvalue expression evaluation kind.
+// FIXME: What about non-reference lvalues, like bitfield lvalues and vector
+// lvalues?
+int &getref();
+extern "C" int cleanup_exit_lvalue(bool cond) {
+ int &r = (A(1), ({ if (cond) return 0; (void)0; }), getref());
+ return r;
+}
+// CHECK-LABEL: define{{.*}} i32 @cleanup_exit_lvalue({{.*}})
+// CHECK: call {{.*}} @_ZN1AC1Ei
+// Spill after bar.
+// CHECK: %[[v:[^ ]*]] = call dereferenceable(4) i32* @_Z6getrefv({{.*}})
+// CHECK-NEXT: store i32* %[[v]], i32** %[[tmp:[^, ]*]]
+// Do cleanup.
+// CHECK: call {{.*}} @_ZN1AD1Ev
+// CHECK: switch
+// Reload before v assignment.
+// CHECK: %[[v:[^ ]*]] = load i32*, i32** %[[tmp]]
+// CHECK-NEXT: store i32* %[[v]], i32** %r
+
+// Bind the reference to a byval argument. It is not an instruction or Constant,
+// so it's a bit of a corner case.
+struct ByVal { int x[3]; };
+extern "C" int cleanup_exit_lvalue_byval(bool cond, ByVal arg) {
+ ByVal &r = (A(1), ({ if (cond) return 0; (void)ByVal(); }), arg);
+ return r.x[0];
+}
+// CHECK-LABEL: define{{.*}} i32 @cleanup_exit_lvalue_byval({{.*}}, %struct.ByVal* byval align 4 %arg)
+// CHECK: call {{.*}} @_ZN1AC1Ei
+// CHECK: call {{.*}} @_ZN1AD1Ev
+// CHECK: switch
+// CHECK: store %struct.ByVal* %arg, %struct.ByVal** %r
+
+// Bind the reference to a local variable. We don't need to spill it. Binding a
+// reference to it doesn't generate any instructions.
+extern "C" int cleanup_exit_lvalue_local(bool cond) {
+ int local = 42;
+ int &r = (A(1), ({ if (cond) return 0; (void)0; }), local);
+ return r;
+}
+// CHECK-LABEL: define{{.*}} i32 @cleanup_exit_lvalue_local({{.*}})
+// CHECK: %local = alloca i32
+// CHECK: store i32 42, i32* %local
+// CHECK: call {{.*}} @_ZN1AC1Ei
+// CHECK-NOT: store i32* %local
+// CHECK: call {{.*}} @_ZN1AD1Ev
+// CHECK: switch
+// CHECK: store i32* %local, i32** %r, align 4
+
+// We handle ExprWithCleanups for complex evaluation type separately, and it had
+// the same bug.
+_Complex float bar_complex(A, int);
+extern "C" int cleanup_exit_complex(bool b) {
+ _Complex float v = bar_complex(A(1), ({ if (b) return 42; 13; }));
+ return (float)v;
+}
+
+// CHECK-LABEL: define{{.*}} i32 @cleanup_exit_complex({{.*}})
+// CHECK: call {{.*}} @_ZN1AC1Ei
+// Spill after bar.
+// CHECK: call {{.*}} @_Z11bar_complex1Ai({{.*}})
+// CHECK: store float %{{.*}}, float* %[[tmp1:[^, ]*]]
+// CHECK: store float %{{.*}}, float* %[[tmp2:[^, ]*]]
+// Do cleanup.
+// CHECK: call {{.*}} @_ZN1AD1Ev
+// CHECK: switch
+// Reload before v assignment.
+// CHECK: %[[v1:[^ ]*]] = load float, float* %[[tmp1]]
+// CHECK: %[[v2:[^ ]*]] = load float, float* %[[tmp2]]
+// CHECK: store float %[[v1]], float* %v.realp
+// CHECK: store float %[[v2]], float* %v.imagp
diff --git a/src/llvm-project/clang/test/CodeGenCXX/strict-vtable-pointers.cpp b/src/llvm-project/clang/test/CodeGenCXX/strict-vtable-pointers.cpp
new file mode 100644
index 0000000..098c779
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/strict-vtable-pointers.cpp
@@ -0,0 +1,593 @@
+// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -fstrict-vtable-pointers -std=c++11 -disable-llvm-passes -O2 -emit-llvm -o %t.ll
+// RUN: FileCheck --check-prefix=CHECK-CTORS %s < %t.ll
+// RUN: FileCheck --check-prefix=CHECK-NEW %s < %t.ll
+// RUN: FileCheck --check-prefix=CHECK-DTORS %s < %t.ll
+// RUN: FileCheck --check-prefix=CHECK-LINK-REQ %s < %t.ll
+
+typedef __typeof__(sizeof(0)) size_t;
+void *operator new(size_t, void *) throw();
+using uintptr_t = unsigned long long;
+
+struct NotTrivialDtor {
+ ~NotTrivialDtor();
+};
+
+struct DynamicBase1 {
+ NotTrivialDtor obj;
+ virtual void foo();
+};
+
+struct DynamicDerived : DynamicBase1 {
+ void foo() override;
+};
+
+struct DynamicBase2 {
+ virtual void bar();
+ ~DynamicBase2() {
+ bar();
+ }
+};
+
+struct DynamicDerivedMultiple : DynamicBase1, DynamicBase2 {
+ void foo() override;
+ void bar() override;
+};
+
+struct StaticBase {
+ NotTrivialDtor obj;
+ void bar();
+};
+
+struct DynamicFromStatic : StaticBase {
+ virtual void bar();
+};
+
+struct DynamicFromVirtualStatic1 : virtual StaticBase {
+};
+
+struct DynamicFromVirtualStatic2 : virtual StaticBase {
+};
+
+struct DynamicFrom2Virtuals : DynamicFromVirtualStatic1,
+ DynamicFromVirtualStatic2 {
+};
+
+// CHECK-NEW-LABEL: define void @_Z12LocalObjectsv()
+// CHECK-NEW-NOT: @llvm.launder.invariant.group.p0i8(
+// CHECK-NEW-LABEL: {{^}}}
+void LocalObjects() {
+ DynamicBase1 DB;
+ DB.foo();
+ DynamicDerived DD;
+ DD.foo();
+
+ DynamicBase2 DB2;
+ DB2.bar();
+
+ StaticBase SB;
+ SB.bar();
+
+ DynamicDerivedMultiple DDM;
+ DDM.foo();
+ DDM.bar();
+
+ DynamicFromStatic DFS;
+ DFS.bar();
+ DynamicFromVirtualStatic1 DFVS1;
+ DFVS1.bar();
+ DynamicFrom2Virtuals DF2V;
+ DF2V.bar();
+}
+
+struct DynamicFromVirtualStatic1;
+// CHECK-CTORS-LABEL: define linkonce_odr void @_ZN25DynamicFromVirtualStatic1C1Ev
+// CHECK-CTORS-NOT: @llvm.launder.invariant.group.p0i8(
+// CHECK-CTORS-LABEL: {{^}}}
+
+struct DynamicFrom2Virtuals;
+// CHECK-CTORS-LABEL: define linkonce_odr void @_ZN20DynamicFrom2VirtualsC1Ev
+// CHECK-CTORS: call i8* @llvm.launder.invariant.group.p0i8(
+// CHECK-CTORS-LABEL: {{^}}}
+
+// CHECK-NEW-LABEL: define void @_Z9Pointers1v()
+// CHECK-NEW-NOT: @llvm.launder.invariant.group.p0i8(
+// CHECK-NEW-LABEL: call void @_ZN12DynamicBase1C1Ev(
+
+// CHECK-NEW: %[[THIS3:.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* %[[THIS2:.*]])
+// CHECK-NEW: %[[THIS4:.*]] = bitcast i8* %[[THIS3]] to %[[DynamicDerived:.*]]*
+// CHECK-NEW: call void @_ZN14DynamicDerivedC1Ev(%[[DynamicDerived:.*]]* %[[THIS4]])
+// CHECK-NEW-LABEL: {{^}}}
+void Pointers1() {
+ DynamicBase1 *DB = new DynamicBase1;
+ DB->foo();
+
+ DynamicDerived *DD = new (DB) DynamicDerived;
+ DD->foo();
+ DD->~DynamicDerived();
+}
+
+// CHECK-NEW-LABEL: define void @_Z14HackingObjectsv()
+// CHECK-NEW: call void @_ZN12DynamicBase1C1Ev
+// CHECK-NEW: call i8* @llvm.launder.invariant.group.p0i8(
+// CHECK-NEW: call void @_ZN14DynamicDerivedC1Ev(
+// CHECK-NEW: call i8* @llvm.launder.invariant.group.p0i8(
+// CHECK-NEW: call void @_ZN12DynamicBase1C1Ev(
+// CHECK-NEW-LABEL: {{^}}}
+void HackingObjects() {
+ DynamicBase1 DB;
+ DB.foo();
+
+ DynamicDerived *DB2 = new (&DB) DynamicDerived;
+ // Using DB now is prohibited.
+ DB2->foo();
+ DB2->~DynamicDerived();
+
+ // We have to get back to the previous type to avoid calling wrong destructor
+ new (&DB) DynamicBase1;
+ DB.foo();
+}
+
+/*** Testing Constructors ***/
+struct DynamicBase1;
+// CHECK-CTORS-LABEL: define linkonce_odr void @_ZN12DynamicBase1C2Ev(
+// CHECK-CTORS-NOT: call i8* @llvm.launder.invariant.group.p0i8(
+// CHECK-CTORS-LABEL: {{^}}}
+
+struct DynamicDerived;
+
+// CHECK-CTORS-LABEL: define linkonce_odr void @_ZN14DynamicDerivedC2Ev(
+// CHECK-CTORS: %[[THIS0:.*]] = load %[[DynamicDerived:.*]]*, %[[DynamicDerived]]** {{.*}}
+// CHECK-CTORS: %[[THIS1:.*]] = bitcast %[[DynamicDerived:.*]]* %[[THIS0]] to i8*
+// CHECK-CTORS: %[[THIS2:.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* %[[THIS1:.*]])
+// CHECK-CTORS: %[[THIS3:.*]] = bitcast i8* %[[THIS2]] to %[[DynamicDerived]]*
+// CHECK-CTORS: %[[THIS4:.*]] = bitcast %[[DynamicDerived]]* %[[THIS3]] to %[[DynamicBase:.*]]*
+// CHECK-CTORS: call void @_ZN12DynamicBase1C2Ev(%[[DynamicBase]]* %[[THIS4]])
+
+// CHECK-CTORS: %[[THIS5:.*]] = bitcast %struct.DynamicDerived* %[[THIS0]] to i32 (...)***
+// CHECK-CTORS: store {{.*}} %[[THIS5]]
+// CHECK-CTORS-LABEL: {{^}}}
+
+struct DynamicDerivedMultiple;
+// CHECK-CTORS-LABEL: define linkonce_odr void @_ZN22DynamicDerivedMultipleC2Ev(
+
+// CHECK-CTORS: %[[THIS0:.*]] = load %[[CLASS:.*]]*, %[[CLASS]]** {{.*}}
+// CHECK-CTORS: %[[THIS1:.*]] = bitcast %[[CLASS:.*]]* %[[THIS0]] to i8*
+// CHECK-CTORS: %[[THIS2:.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* %[[THIS1]])
+// CHECK-CTORS: %[[THIS3:.*]] = bitcast i8* %[[THIS2]] to %[[CLASS]]*
+// CHECK-CTORS: %[[THIS4:.*]] = bitcast %[[CLASS]]* %[[THIS3]] to %[[BASE_CLASS:.*]]*
+// CHECK-CTORS: call void @_ZN12DynamicBase1C2Ev(%[[BASE_CLASS]]* %[[THIS4]])
+
+// CHECK-CTORS: call i8* @llvm.launder.invariant.group.p0i8(
+
+// CHECK-CTORS: call void @_ZN12DynamicBase2C2Ev(
+// CHECK-CTORS-NOT: @llvm.launder.invariant.group.p0i8
+
+// CHECK-CTORS: %[[THIS10:.*]] = bitcast %struct.DynamicDerivedMultiple* %[[THIS0]] to i32 (...)***
+// CHECK-CTORS: store {{.*}} @_ZTV22DynamicDerivedMultiple, i32 0, inrange i32 0, i32 2) {{.*}} %[[THIS10]]
+// CHECK-CTORS: %[[THIS11:.*]] = bitcast %struct.DynamicDerivedMultiple* %[[THIS0]] to i8*
+// CHECK-CTORS: %[[THIS_ADD:.*]] = getelementptr inbounds i8, i8* %[[THIS11]], i64 16
+// CHECK-CTORS: %[[THIS12:.*]] = bitcast i8* %[[THIS_ADD]] to i32 (...)***
+
+// CHECK-CTORS: store {{.*}} @_ZTV22DynamicDerivedMultiple, i32 0, inrange i32 1, i32 2) {{.*}} %[[THIS12]]
+// CHECK-CTORS-LABEL: {{^}}}
+
+struct DynamicFromStatic;
+// CHECK-CTORS-LABEL: define linkonce_odr void @_ZN17DynamicFromStaticC2Ev(
+// CHECK-CTORS-NOT: @llvm.launder.invariant.group.p0i8(
+// CHECK-CTORS-LABEL: {{^}}}
+
+struct A {
+ virtual void foo();
+ int m;
+};
+struct B : A {
+ void foo() override;
+};
+
+union U {
+ A a;
+ B b;
+};
+
+void changeToB(U *u);
+void changeToA(U *u);
+
+void g2(A *a) {
+ a->foo();
+}
+// We have to guard access to union fields with invariant.group, because
+// it is very easy to skip the barrier with unions. In this example the inlined
+// g2 will produce loads with the same !invariant.group metadata, and
+// u->a and u->b would use the same pointer.
+// CHECK-NEW-LABEL: define void @_Z14UnionsBarriersP1U
+void UnionsBarriers(U *u) {
+ // CHECK-NEW: call void @_Z9changeToBP1U(
+ changeToB(u);
+ // CHECK-NEW: call i8* @llvm.launder.invariant.group.p0i8(i8*
+ // CHECK-NEW: call void @_Z2g2P1A(%struct.A*
+ g2(&u->b);
+ // CHECK-NEW: call void @_Z9changeToAP1U(%union.U*
+ changeToA(u);
+ // CHECK-NEW: call i8* @llvm.launder.invariant.group.p0i8(i8*
+ // call void @_Z2g2P1A(%struct.A* %a)
+ g2(&u->a);
+ // CHECK-NEW-NOT: call i8* @llvm.launder.invariant.group.p0i8(i8*
+}
+
+struct HoldingVirtuals {
+ A a;
+};
+
+struct Empty {};
+struct AnotherEmpty {
+ Empty e;
+};
+union NoVptrs {
+ int a;
+ AnotherEmpty empty;
+};
+void take(AnotherEmpty &);
+
+// CHECK-NEW-LABEL: noBarriers
+void noBarriers(NoVptrs &noVptrs) {
+ // CHECK-NEW-NOT: call i8* @llvm.launder.invariant.group.p0i8(i8*
+ // CHECK-NEW: 42
+ noVptrs.a += 42;
+ // CHECK-NEW-NOT: call i8* @llvm.launder.invariant.group.p0i8(i8*
+ // CHECK-NEW: call void @_Z4takeR12AnotherEmpty(
+ take(noVptrs.empty);
+}
+
+union U2 {
+ HoldingVirtuals h;
+ int z;
+};
+void take(HoldingVirtuals &);
+
+// CHECK-NEW-LABEL: define void @_Z15UnionsBarriers2R2U2
+void UnionsBarriers2(U2 &u) {
+ // CHECK-NEW-NOT: call i8* @llvm.launder.invariant.group.p0i8(i8*
+ // CHECK-NEW: 42
+ u.z += 42;
+ // CHECK-NEW: call i8* @llvm.launder.invariant.group.p0i8(i8*
+ // CHECK-NEW: call void @_Z4takeR15HoldingVirtuals(
+ take(u.h);
+}
+
+struct VirtualInBase : HoldingVirtuals, Empty {
+};
+
+struct VirtualInVBase : virtual Empty, virtual HoldingVirtuals {
+};
+
+// It has vtable by virtual inheritance.
+struct VirtualInheritance : virtual Empty {
+};
+
+union U3 {
+ VirtualInBase v1;
+ VirtualInBase v2;
+ VirtualInheritance v3;
+ int z;
+};
+
+void take(VirtualInBase &);
+void take(VirtualInVBase &);
+void take(VirtualInheritance &);
+
+void UnionsBarrier3(U3 &u) {
+ // CHECK-NEW-NOT: call i8* @llvm.launder.invariant.group.p0i8(i8*
+ // CHECK-NEW: 42
+ u.z += 42;
+ // CHECK-NEW: call i8* @llvm.launder.invariant.group.p0i8(i8*
+ // CHECK-NEW: call void @_Z4takeR13VirtualInBase(
+ take(u.v1);
+ // CHECK-NEW: call i8* @llvm.launder.invariant.group.p0i8(i8*
+ // CHECK-NEW: call void @_Z4takeR13VirtualInBase(
+ take(u.v2);
+
+ // CHECK-NEW: call i8* @llvm.launder.invariant.group.p0i8(i8*
+ // CHECK-NEW: call void @_Z4takeR18VirtualInheritance(
+ take(u.v3);
+}
+
+// CHECK-NEW-LABEL: define void @_Z7comparev()
+void compare() {
+ A *a = new A;
+ a->foo();
+ // CHECK-NEW: call i8* @llvm.launder.invariant.group.p0i8(i8*
+ A *b = new (a) B;
+
+ // CHECK-NEW: %[[a:.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8*
+ // CHECK-NEW: %[[a2:.*]] = bitcast i8* %[[a]] to %struct.A*
+ // CHECK-NEW: %[[b:.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8*
+ // CHECK-NEW: %[[b2:.*]] = bitcast i8* %[[b]] to %struct.A*
+ // CHECK-NEW: %cmp = icmp eq %struct.A* %[[a2]], %[[b2]]
+ if (a == b)
+ b->foo();
+}
+
+// CHECK-NEW-LABEL: compare2
+bool compare2(A *a, A *a2) {
+ // CHECK-NEW: %[[a:.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8*
+ // CHECK-NEW: %[[a2:.*]] = bitcast i8* %[[a]] to %struct.A*
+ // CHECK-NEW: %[[b:.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8*
+ // CHECK-NEW: %[[b2:.*]] = bitcast i8* %[[b]] to %struct.A*
+ // CHECK-NEW: %cmp = icmp ult %struct.A* %[[a2]], %[[b2]]
+ return a < a2;
+}
+// CHECK-NEW-LABEL: compareIntPointers
+bool compareIntPointers(int *a, int *b) {
+ // CHECK-NEW-NOT: call i8* @llvm.strip.invariant.group
+ return a == b;
+}
+
+struct HoldingOtherVirtuals {
+ B b;
+};
+
+// There is no need to add barriers for comparision of pointer to classes
+// that are not dynamic.
+// CHECK-NEW-LABEL: compare5
+bool compare5(HoldingOtherVirtuals *a, HoldingOtherVirtuals *b) {
+ // CHECK-NEW-NOT: call i8* @llvm.strip.invariant.group
+ return a == b;
+}
+// CHECK-NEW-LABEL: compareNull
+bool compareNull(A *a) {
+ // CHECK-NEW-NOT: call i8* @llvm.strip.invariant.group
+
+ if (a != nullptr)
+ return false;
+ if (!a)
+ return false;
+ return a == nullptr;
+}
+
+struct X;
+// We have to also introduce the barriers if comparing pointers to incomplete
+// objects
+// CHECK-NEW-LABEL: define zeroext i1 @_Z8compare4P1XS0_
+bool compare4(X *x, X *x2) {
+ // CHECK-NEW: %[[x:.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8*
+ // CHECK-NEW: %[[xp:.*]] = bitcast i8* %[[x]] to %struct.X*
+ // CHECK-NEW: %[[x2:.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8*
+ // CHECK-NEW: %[[x2p:.*]] = bitcast i8* %[[x2]] to %struct.X*
+ // CHECK-NEW: %cmp = icmp eq %struct.X* %[[xp]], %[[x2p]]
+ return x == x2;
+}
+
+// CHECK-NEW-LABEL: define void @_Z7member1P20HoldingOtherVirtuals(
+void member1(HoldingOtherVirtuals *p) {
+
+ // CHECK-NEW-NOT: call i8* @llvm.strip.invariant.group.p0i8(
+ (void)p->b;
+}
+
+// CHECK-NEW-LABEL: member2
+void member2(A *a) {
+ // CHECK-NEW: call i8* @llvm.strip.invariant.group.p0i8
+ (void)a->m;
+}
+
+// Check if from comparison of addresses of member we can't infer the equality
+// of ap and bp.
+// CHECK-NEW-LABEL: @_Z18testCompareMembersv(
+void testCompareMembers() {
+ // CHECK-NEW: [[AP:%.*]] = alloca %struct.A*
+ // CHECK-NEW: [[APM:%.*]] = alloca i32*
+ // CHECK-NEW: [[BP:%.*]] = alloca %struct.B*
+ // CHECK-NEW: [[BPM:%.*]] = alloca i32*
+
+ A *ap = new A;
+ // CHECK-NEW: call void %{{.*}}(%struct.A* %{{.*}})
+ ap->foo();
+ // CHECK-NEW: [[TMP7:%.*]] = load %struct.A*, %struct.A** [[AP]]
+ // CHECK-NEW: [[TMP8:%.*]] = bitcast %struct.A* [[TMP7]] to i8*
+ // CHECK-NEW: [[TMP9:%.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* [[TMP8]])
+ // CHECK-NEW: [[TMP10:%.*]] = bitcast i8* [[TMP9]] to %struct.A*
+ // CHECK-NEW: [[M:%.*]] = getelementptr inbounds [[STRUCT_A:%.*]], %struct.A* [[TMP10]], i32 0, i32 1
+ // CHECK-NEW: store i32* [[M]], i32** [[APM]]
+ int *const apm = &ap->m;
+
+ B *bp = new (ap) B;
+
+ // CHECK-NEW: [[TMP20:%.*]] = load %struct.B*, %struct.B** [[BP]]
+ // CHECK-NEW: [[TMP21:%.*]] = bitcast %struct.B* [[TMP20]] to %struct.A*
+ // CHECK-NEW: [[TMP22:%.*]] = bitcast %struct.A* [[TMP21]] to i8*
+ // CHECK-NEW: [[TMP23:%.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* [[TMP22]])
+ // CHECK-NEW: [[TMP24:%.*]] = bitcast i8* [[TMP23]] to %struct.A*
+ // CHECK-NEW: [[M4:%.*]] = getelementptr inbounds [[STRUCT_A]], %struct.A* [[TMP24]], i32 0, i32 1
+ // CHECK-NEW: store i32* [[M4]], i32** [[BPM]]
+ int *const bpm = &bp->m;
+
+ // CHECK-NEW: [[TMP25:%.*]] = load i32*, i32** [[APM]]
+ // CHECK-NEW: [[TMP26:%.*]] = load i32*, i32** [[BPM]]
+ // CHECK-NEW-NOT: strip.invariant.group
+ // CHECK-NEW-NOT: launder.invariant.group
+ // CHECK-NEW: [[CMP:%.*]] = icmp eq i32* [[TMP25]], [[TMP26]]
+ if (apm == bpm) {
+ bp->foo();
+ }
+}
+
+// CHECK-NEW-LABEL: define void @_Z9testCast1P1A(%struct.A*
+void testCast1(A *a) {
+ // Here we get rid of dynamic info
+ // CHECK-NEW: call i8* @llvm.strip.invariant.group
+ auto *v = (void *)a;
+
+ // CHECK-NEW: call i8* @llvm.strip.invariant.group
+ auto i2 = (uintptr_t)a;
+ (void)i2;
+
+ // CHECK-NEW-NOT: @llvm.strip.invariant.group
+ // CHECK-NEW-NOT: @llvm.launder.invariant.group
+
+ // The information is already stripped
+ auto i = (uintptr_t)v;
+}
+
+struct Incomplete;
+// CHECK-NEW-LABEL: define void @_Z9testCast2P10Incomplete(%struct.Incomplete*
+void testCast2(Incomplete *I) {
+ // Here we get rid of potential dynamic info
+ // CHECK-NEW: call i8* @llvm.strip.invariant.group
+ auto *v = (void *)I;
+
+ // CHECK-NEW: call i8* @llvm.strip.invariant.group
+ auto i2 = (uintptr_t)I;
+ (void)i2;
+
+ // CHECK-NEW-NOT: @llvm.strip.invariant.group
+ // CHECK-NEW-NOT: @llvm.launder.invariant.group
+
+ // The information is already stripped
+ auto i = (uintptr_t)v;
+}
+
+// CHECK-NEW-LABEL: define void @_Z9testCast3y(
+void testCast3(uintptr_t i) {
+ // CHECK-NEW-NOT: @llvm.strip.invariant.group
+ // CHECK-NEW: @llvm.launder.invariant.group
+ A *a3 = (A *)i;
+ (void)a3;
+
+ auto *v2 = (void *)i;
+
+ // CHECK-NEW: @llvm.launder.invariant.group
+ A *a2 = (A *)v2;
+ (void)a2;
+
+ // CHECK-NEW-NOT: @llvm.launder.invariant.group
+ auto *v3 = (void *)i;
+ (void)v3;
+}
+
+// CHECK-NEW-LABEL: define void @_Z9testCast4y(
+void testCast4(uintptr_t i) {
+ // CHECK-NEW-NOT: @llvm.strip.invariant.group
+ // CHECK-NEW: @llvm.launder.invariant.group
+ auto *a3 = (Incomplete *)i;
+ (void)a3;
+
+ // CHECK-NEW: @llvm.launder.invariant.group
+ auto *v2 = (void *)i;
+ // CHECK-NEW-NOT: @llvm.launder.invariant.group
+ auto *a2 = (Incomplete *)v2;
+ (void)a2;
+}
+
+// CHECK-NEW-LABEL: define void @_Z9testCast5P1B(
+void testCast5(B *b) {
+ // CHECK-NEW-NOT: @llvm.strip.invariant.group
+ // CHECK-NEW-NOT: @llvm.launder.invariant.group
+ A *a = b;
+ (void)a;
+
+ auto *b2 = (B *)a;
+ (void)b2;
+}
+
+// CHECK-NEW-LABEL: define void @_Z9testCast6P1A(
+void testCast6(A *a) {
+
+ // CHECK-NEW: @llvm.strip.invariant.group
+ auto *I = (Incomplete *)a;
+ (void)I;
+ // CHECK-NEW: @llvm.launder.invariant.group
+ auto *a2 = (A *)I;
+ (void)a2;
+
+ // CHECK-NEW: @llvm.strip.invariant.group
+ auto *E = (Empty *)a;
+ (void)E;
+
+ // CHECK-NEW: @llvm.launder.invariant.group
+ auto *a3 = (A *)E;
+ (void)a3;
+
+ // CHECK-NEW-NOT: @llvm.strip.invariant.group
+ auto i = (uintptr_t)E;
+ (void)i;
+}
+
+class Incomplete2;
+// CHECK-NEW-LABEL: define void @_Z9testCast7P10Incomplete(
+void testCast7(Incomplete *I) {
+ // CHECK-NEW-NOT: @llvm.strip.invariant.group
+
+ // Incomplete2 could be dynamic where Incomplete may not be dynamic, thus
+ // launder is needed. We don't strip firstly because launder is sufficient.
+
+ // CHECK-NEW: @llvm.launder.invariant.group
+ auto *I2 = (Incomplete2 *)I;
+ (void)I2;
+ // CHECK-NEW-LABEL: ret void
+}
+
+template <typename Base>
+struct PossiblyDerivingFromDynamicBase : Base {
+};
+
+// CHECK-NEW-LABEL: define void @_Z9testCast8P10Incomplete(
+void testCast8(Incomplete *I) {
+ // CHECK-NEW-NOT: @llvm.strip.invariant.group
+ // CHECK-NEW: @llvm.launder.invariant.group
+ auto *P = (PossiblyDerivingFromDynamicBase<Incomplete> *)I;
+ (void)P;
+
+ // CHECK-NEW: @llvm.launder.invariant.group
+ auto *P2 = (PossiblyDerivingFromDynamicBase<Empty> *)I;
+ (void)P2;
+
+ // CHECK-NEW: @llvm.launder.invariant.group
+ auto *P3 = (PossiblyDerivingFromDynamicBase<A> *)I;
+ (void)P3;
+
+ // CHECK-NEW-NOT: @llvm.launder.invariant.group
+ auto *a3 = (A *)P3;
+
+ // CHECK-NEW-LABEL: ret void
+}
+
+// CHECK-NEW-LABEL: define void @_Z9testCast9
+void testCast9(PossiblyDerivingFromDynamicBase<Incomplete> *P) {
+ // CHECK-NEW: @llvm.strip.invariant.group
+ auto *V = (void *)P;
+
+ // CHECK-NEW-LABEL: ret void
+}
+
+/** DTORS **/
+// CHECK-DTORS-LABEL: define linkonce_odr void @_ZN10StaticBaseD2Ev(
+// CHECK-DTORS-NOT: call i8* @llvm.launder.invariant.group.p0i8(
+// CHECK-DTORS-LABEL: {{^}}}
+
+// CHECK-DTORS-LABEL: define linkonce_odr void @_ZN25DynamicFromVirtualStatic2D2Ev(
+// CHECK-DTORS-NOT: invariant.barrier
+// CHECK-DTORS-LABEL: {{^}}}
+
+// CHECK-DTORS-LABEL: define linkonce_odr void @_ZN17DynamicFromStaticD2Ev
+// CHECK-DTORS-NOT: call i8* @llvm.launder.invariant.group.p0i8(
+// CHECK-DTORS-LABEL: {{^}}}
+
+// CHECK-DTORS-LABEL: define linkonce_odr void @_ZN22DynamicDerivedMultipleD2Ev(
+
+// CHECK-DTORS-LABEL: define linkonce_odr void @_ZN12DynamicBase2D2Ev(
+// CHECK-DTORS: call i8* @llvm.launder.invariant.group.p0i8(
+// CHECK-DTORS-LABEL: {{^}}}
+
+// CHECK-DTORS-LABEL: define linkonce_odr void @_ZN12DynamicBase1D2Ev
+// CHECK-DTORS: call i8* @llvm.launder.invariant.group.p0i8(
+// CHECK-DTORS-LABEL: {{^}}}
+
+// CHECK-DTORS-LABEL: define linkonce_odr void @_ZN14DynamicDerivedD2Ev
+// CHECK-DTORS-NOT: call i8* @llvm.launder.invariant.group.p0i8(
+// CHECK-DTORS-LABEL: {{^}}}
+
+// CHECK-LINK-REQ: !llvm.module.flags = !{![[FIRST:[0-9]+]], ![[SEC:[0-9]+]]{{.*}}}
+
+// CHECK-LINK-REQ: ![[FIRST]] = !{i32 1, !"StrictVTablePointers", i32 1}
+// CHECK-LINK-REQ: ![[SEC]] = !{i32 3, !"StrictVTablePointersRequirement", ![[META:.*]]}
+// CHECK-LINK-REQ: ![[META]] = !{!"StrictVTablePointers", i32 1}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/switch-case-folding-1.cpp b/src/llvm-project/clang/test/CodeGenCXX/switch-case-folding-1.cpp
new file mode 100644
index 0000000..1daeecf
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/switch-case-folding-1.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 %s -emit-llvm-only
+// CHECK that we don't crash.
+
+int test(int val){
+ int x = 12;
+ // Make sure we don't crash when constant folding the case 4
+ // statement due to the case 5 statement contained in the do loop
+ switch (val) {
+ case 4: do {
+ switch (6) {
+ case 6: {
+ case 5: x++;
+ };
+ };
+ } while (x < 100);
+ }
+ return x;
+}
+
+int main(void) {
+ return test(4);
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/switch-case-folding-2.cpp b/src/llvm-project/clang/test/CodeGenCXX/switch-case-folding-2.cpp
new file mode 100644
index 0000000..cfb8447
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/switch-case-folding-2.cpp
@@ -0,0 +1,108 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s
+
+extern int printf(const char*, ...);
+
+// CHECK-LABEL: @_Z4testi(
+int test(int val){
+ switch (val) {
+ case 4:
+ do {
+ switch (6) {
+ // CHECK: call i32 (i8*, ...) @_Z6printfPKcz
+ case 6: do { case 5: printf("bad\n"); } while (0);
+ };
+ } while (0);
+ }
+ return 0;
+}
+
+int main(void) {
+ return test(5);
+}
+
+// CHECK-LABEL: @_Z10other_testv(
+void other_test() {
+ switch(0) {
+ case 0:
+ do {
+ default:;
+ } while(0);
+ }
+}
+
+struct X { X(); ~X(); };
+
+void dont_call();
+void foo();
+
+// CHECK-LABEL: @_Z13nested_scopesv(
+void nested_scopes() {
+ switch (1) {
+ case 0:
+ // CHECK-NOT: @_Z9dont_callv(
+ dont_call();
+ break;
+
+ default:
+ // CHECK: call {{.*}} @_ZN1XC1Ev(
+ // CHECK: call {{.*}} @_Z3foov(
+ // CHECK-NOT: call {{.*}} @_Z3foov(
+ // CHECK: call {{.*}} @_ZN1XD1Ev(
+ { X x; foo(); }
+
+ // CHECK: call {{.*}} @_ZN1XC1Ev(
+ // CHECK: call {{.*}} @_Z3foov(
+ // CHECK: call {{.*}} @_ZN1XD1Ev(
+ { X x; foo(); }
+
+ // CHECK: call {{.*}} @_ZN1XC1Ev(
+ // CHECK: call {{.*}} @_Z3foov(
+ // CHECK: call {{.*}} @_ZN1XD1Ev(
+ { X x; foo(); }
+ break;
+ }
+}
+
+// CHECK-LABEL: @_Z17scope_fallthroughv(
+void scope_fallthrough() {
+ switch (1) {
+ // CHECK: call {{.*}} @_ZN1XC1Ev(
+ // CHECK-NOT: call {{.*}} @_Z3foov(
+ // CHECK: call {{.*}} @_ZN1XD1Ev(
+ { default: X x; }
+ // CHECK: call {{.*}} @_Z3foov(
+ foo();
+ break;
+ }
+}
+
+// CHECK-LABEL: @_Z12hidden_breakb(
+void hidden_break(bool b) {
+ switch (1) {
+ default:
+ // CHECK: br
+ if (b)
+ break;
+ // CHECK: call {{.*}} @_Z3foov(
+ foo();
+ break;
+ }
+}
+
+// CHECK-LABEL: @_Z10hidden_varv(
+int hidden_var() {
+ switch (1) {
+ // CHECK: %[[N:.*]] = alloca i32
+ case 0: int n;
+ // CHECK: store i32 0, i32* %[[N]]
+ // CHECK: load i32, i32* %[[N]]
+ // CHECK: ret
+ default: n = 0; return n;
+ }
+}
+
+// CHECK-LABEL: @_Z13case_in_labelv(
+void case_in_label() {
+ // CHECK: br label %
+ switch (1) case 1: foo: case 0: goto foo;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/switch-case-folding.cpp b/src/llvm-project/clang/test/CodeGenCXX/switch-case-folding.cpp
new file mode 100644
index 0000000..d4444b1
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/switch-case-folding.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 %s -emit-llvm-only
+// CHECK that we don't crash.
+
+int main(void){
+ int x = 12;
+ // Make sure we don't crash when constant folding the case 4
+ // statement due to the case 5 statement contained in the do loop
+ switch (4) {
+ case 4: do {
+ switch (6) {
+ case 6: {
+ case 5: x++;
+ };
+ };
+ } while (x < 100);
+ }
+ return x;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/tail-padding.cpp b/src/llvm-project/clang/test/CodeGenCXX/tail-padding.cpp
new file mode 100644
index 0000000..b8b9e4c
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/tail-padding.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
+
+// PR36992
+namespace Implicit {
+ struct A { char c; A(const A&); };
+ struct B { int n; char c[3]; ~B(); };
+ struct C : B, virtual A {};
+ static_assert(sizeof(C) == sizeof(void*) + 8);
+ C f(C c) { return c; }
+
+ // CHECK: define {{.*}} @_ZN8Implicit1CC1EOS0_
+ // CHECK: call {{.*}} @_ZN8Implicit1AC2ERKS0_(
+ // Note: this must memcpy 7 bytes, not 8, to avoid trampling over the virtual base class.
+ // CHECK: call void @llvm.memcpy.p0i8.p0i8.i{{32|64}}(i8* {{.*}}, i8* {{.*}}, i{{32|64}} 7, i1 false)
+ // CHECK: store i32 {{.*}} @_ZTVN8Implicit1CE
+}
+
+namespace InitWithinNVSize {
+ // This is the same as the previous test, except that the A base lies
+ // entirely within the nvsize of C. This makes it valid to copy at the
+ // full width.
+ struct A { char c; A(const A&); };
+ struct B { int n; char c[3]; ~B(); };
+ struct C : B, virtual A { char x; };
+ static_assert(sizeof(C) > sizeof(void*) + 8);
+ C f(C c) { return c; }
+
+ // CHECK: define {{.*}} @_ZN16InitWithinNVSize1CC1EOS0_
+ // CHECK: call {{.*}} @_ZN16InitWithinNVSize1AC2ERKS0_(
+ // This copies over the 'C::x' member, but that's OK because we've not initialized it yet.
+ // CHECK: call void @llvm.memcpy.p0i8.p0i8.i{{32|64}}(i8* {{.*}}, i8* {{.*}}, i{{32|64}} 8, i1 false)
+ // CHECK: store i32 {{.*}} @_ZTVN16InitWithinNVSize1CE
+ // CHECK: store i8
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/temp-order.cpp b/src/llvm-project/clang/test/CodeGenCXX/temp-order.cpp
new file mode 100644
index 0000000..67cd4b7
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/temp-order.cpp
@@ -0,0 +1,226 @@
+// Output file should have no calls to error() with folding.
+// RUN: %clang_cc1 -triple i386-unknown-unknown -mllvm -inline-threshold=1024 -O3 -emit-llvm -o %t %s
+// RUN: FileCheck %s < %t
+
+static unsigned pow(unsigned Base, unsigned Power) {
+ unsigned Val = 1;
+ while (Power--)
+ Val *= Base;
+ return Val;
+}
+
+struct TempTracker {
+ unsigned Product, Index;
+
+ TempTracker() : Product(1), Index(0) {}
+
+};
+
+// FIXME: This can be used to check elision as well, if P = 0 hacks are removed.
+struct A {
+ TempTracker &TT;
+ mutable unsigned P;
+ bool Truth;
+
+ A(TempTracker &_TT, unsigned _P, bool _Truth = true)
+ : TT(_TT), P(_P), Truth(_Truth) {}
+ A(const A &RHS) : TT(RHS.TT), P(RHS.P), Truth(RHS.Truth) { RHS.P = 0; }
+ ~A() {
+ if (P)
+ TT.Product *= pow(P, ++TT.Index);
+ }
+
+ A &operator=(const A &RHS) {
+ TT = RHS.TT;
+ P = RHS.P;
+ Truth = RHS.Truth;
+ RHS.P = 0;
+ return *this;
+ }
+
+ operator bool () { return Truth; }
+};
+
+// 3, 7, 2
+static unsigned f0(bool val = false) {
+ TempTracker tt;
+ {
+ A a(tt, 2);
+ if ((A(tt, 3), val))
+ A b(tt, 5);
+ A c(tt, 7);
+ }
+ return tt.Product;
+}
+
+// 3, 5, 7, 2
+static unsigned f1(bool val = true) {
+ TempTracker tt;
+ {
+ A a(tt, 2);
+ if ((A(tt, 3), val))
+ A b(tt, 5);
+ A c(tt, 7);
+ }
+ return tt.Product;
+}
+
+// 5, 3, 7, 2
+static unsigned f2() {
+ TempTracker tt;
+ {
+ A a(tt, 2);
+ if (A b = A(tt, 3))
+ A c(tt, 5);
+ A d(tt, 7);
+ }
+ return tt.Product;
+}
+
+// 7, 3, 11, 2
+static unsigned f3() {
+ TempTracker tt;
+ {
+ A a(tt, 2);
+ if (A b = A(tt, 3, false))
+ A c(tt, 5);
+ else
+ A c(tt, 7);
+ A d(tt, 11);
+ }
+ return tt.Product;
+}
+
+// 3, 7, 2
+static unsigned f4() {
+ TempTracker tt;
+ {
+ A a(tt, 2);
+ while (A b = A(tt, 3, false))
+ A c(tt, 5);
+ A c(tt, 7);
+ }
+ return tt.Product;
+}
+
+// 5, 3, 7, 2
+static unsigned f5() {
+ TempTracker tt;
+ {
+ A a(tt, 2);
+ while (A b = A(tt, 3, true)) {
+ A c(tt, 5);
+ break;
+ }
+ A c(tt, 7);
+ }
+ return tt.Product;
+}
+
+// 3, 7, 11, 5, 13, 2
+static unsigned f6() {
+ TempTracker tt;
+ {
+ A a(tt, 2);
+ for (A b = (A(tt, 3), A(tt, 5)), c = (A(tt, 7), A(tt, 11));;)
+ break;
+ A c(tt, 13);
+ }
+ return tt.Product;
+}
+
+// 5, 2
+static unsigned f7() {
+ TempTracker tt;
+ {
+ (void)((A(tt, 2, false) && A(tt, 3, false)) || A(tt, 5, false));
+ }
+ return tt.Product;
+}
+
+// 5, 2
+static unsigned f8() {
+ TempTracker tt;
+
+ {
+ (void)((A(tt, 2) || A(tt, 3)) && A(tt, 5));
+ }
+ return tt.Product;
+}
+
+extern "C" void error();
+extern "C" void print(const char *Name, unsigned N);
+
+#define ORDER2(a, b) (pow(a, 1) * pow(b, 2))
+#define ORDER3(a, b, c) (ORDER2(a, b) * pow(c, 3))
+#define ORDER4(a, b, c, d) (ORDER3(a, b, c) * pow(d, 4))
+#define ORDER5(a, b, c, d, e) (ORDER4(a, b, c, d) * pow(e, 5))
+#define ORDER6(a, b, c, d, e, f) (ORDER5(a, b, c, d, e) * pow(f, 6))
+void test() {
+// CHECK: call void @print(i8* {{.*}}, i32 1176)
+ print("f0", f0());
+ if (f0() != ORDER3(3, 7, 2))
+ error();
+
+// CHECK: call void @print(i8* {{.*}}, i32 411600)
+ print("f1", f1());
+ if (f1() != ORDER4(3, 5, 7, 2))
+ error();
+
+// CHECK: call void @print(i8* {{.*}}, i32 246960)
+ print("f2", f2());
+ if (f2() != ORDER4(5, 3, 7, 2))
+ error();
+
+// CHECK: call void @print(i8* {{.*}}, i32 1341648)
+ print("f3", f3());
+ if (f3() != ORDER4(7, 3, 11, 2))
+ error();
+
+// CHECK: call void @print(i8* {{.*}}, i32 1176)
+ print("f4", f4());
+ if (f4() != ORDER3(3, 7, 2))
+ error();
+
+// CHECK: call void @print(i8* {{.*}}, i32 246960)
+ print("f5", f5());
+ if (f5() != ORDER4(5, 3, 7, 2))
+ error();
+
+// CHECK: call void @print(i8* {{.*}}, i32 1251552576)
+ print("f6", f6());
+ if (f6() != ORDER6(3, 7, 11, 5, 13, 2))
+ error();
+
+// CHECK: call void @print(i8* {{.*}}, i32 20)
+ print("f7", f7());
+ if (f7() != ORDER2(5, 2))
+ error();
+
+// CHECK: call void @print(i8* {{.*}}, i32 20)
+ print("f8", f8());
+ if (f8() != ORDER2(5, 2))
+ error();
+}
+
+
+
+#ifdef HARNESS
+
+#include <cstdlib>
+#include <cstdio>
+
+extern "C" void error() {
+ abort();
+}
+
+extern "C" void print(const char *name, unsigned N) {
+ printf("%s: %d\n", name, N);
+}
+
+int main() {
+ test();
+ return 0;
+}
+
+#endif
diff --git a/src/llvm-project/clang/test/CodeGenCXX/template-anonymous-types.cpp b/src/llvm-project/clang/test/CodeGenCXX/template-anonymous-types.cpp
new file mode 100644
index 0000000..63685ef
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/template-anonymous-types.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 %s -triple x86_64-unknown-linux-gnu -emit-llvm -w -o - | FileCheck %s
+
+struct S {
+ enum { FOO = 42 };
+ enum { BAR = 42 };
+};
+
+template <typename T> struct X {
+ T value;
+ X(T t) : value(t) {}
+ int f() { return value; }
+};
+
+template <typename T> int f(T t) {
+ X<T> x(t);
+ return x.f();
+}
+
+void test() {
+ // Look for two instantiations, one for FOO's
+ // type and one for BAR's.
+ // CHECK-LABEL: define linkonce_odr i32 @_Z1fIN1SUt_EEiT_(i32 %t)
+ (void)f(S::FOO);
+ // CHECK-LABEL: define linkonce_odr i32 @_Z1fIN1SUt0_EEiT_(i32 %t)
+ (void)f(S::BAR);
+
+ // Now check for the class template instantiations.
+ //
+ // BAR's instantiation of X:
+ // CHECK-LABEL: define linkonce_odr i32 @_ZN1XIN1SUt_EE1fEv(%struct.X* %this)
+ // CHECK-LABEL: define linkonce_odr void @_ZN1XIN1SUt_EEC2ES1_(%struct.X* %this, i32 %t) unnamed_addr
+ //
+ // FOO's instantiation of X:
+ // CHECK-LABEL: define linkonce_odr i32 @_ZN1XIN1SUt0_EE1fEv(%struct.X.0* %this)
+ // CHECK-LABEL: define linkonce_odr void @_ZN1XIN1SUt0_EEC2ES1_(%struct.X.0* %this, i32 %t) unnamed_addr
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/template-anonymous-union-member-initializer.cpp b/src/llvm-project/clang/test/CodeGenCXX/template-anonymous-union-member-initializer.cpp
new file mode 100644
index 0000000..41ae084
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/template-anonymous-union-member-initializer.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -emit-llvm -o %t %s
+template <typename T>
+class A
+{
+ union { void *d; };
+
+public:
+ A() : d(0) { }
+};
+
+A<int> a0;
diff --git a/src/llvm-project/clang/test/CodeGenCXX/template-dependent-bind-temporary.cpp b/src/llvm-project/clang/test/CodeGenCXX/template-dependent-bind-temporary.cpp
new file mode 100644
index 0000000..4c4b3ea
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/template-dependent-bind-temporary.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 %s -emit-llvm -triple %itanium_abi_triple -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-LABEL: define linkonce_odr {{.*}}void @_Z11IntToStringIcEvT_(
+ IntToString('a');
+}
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/template-inner-struct-visibility-hidden.cpp b/src/llvm-project/clang/test/CodeGenCXX/template-inner-struct-visibility-hidden.cpp
new file mode 100644
index 0000000..137792b
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/template-inner-struct-visibility-hidden.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -fvisibility hidden -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
+
+// Verify that symbols are hidden.
+// CHECK: @_ZN1CIiE5Inner6Inner26StaticE = weak_odr hidden global
+// CHECK-LABEL: define weak_odr hidden {{.*}}void @_ZN1CIiE5Inner1fEv
+// CHECK-LABEL: 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/src/llvm-project/clang/test/CodeGenCXX/template-instantiation.cpp b/src/llvm-project/clang/test/CodeGenCXX/template-instantiation.cpp
new file mode 100644
index 0000000..098f18d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/template-instantiation.cpp
@@ -0,0 +1,205 @@
+// RUN: %clang_cc1 %s -O1 -disable-llvm-passes -triple=x86_64-apple-darwin10 -std=c++11 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -O1 -disable-llvm-passes -triple=x86_64-apple-darwin10 -std=c++11 -emit-llvm -o - | FileCheck %s --check-prefix=CHECK2
+
+// Instantiation order varies on different C++ dialects (IE, between C++98 and C++11).
+// CHECK-DAG: @_ZN7PR100011xE = global
+// CHECK-DAG: @_ZTVN5test018stdio_sync_filebufIA3_iEE = weak_odr unnamed_addr constant
+// CHECK-DAG: @_ZN7PR100011SIiE3arrE = linkonce_odr global [3 x i32]
+// CHECK-DAG: @_ZTVN5test018stdio_sync_filebufIA4_iEE = linkonce_odr unnamed_addr constant
+
+// Negative checks go under prefix "CHECK2" to avoid interference with CHECK and CHECK-DAG.
+// CHECK2-NOT: @_ZN7PR100014kBarE = external global i32
+// CHECK2-NOT: @_ZTVN5test118stdio_sync_filebufIwEE = constant
+// CHECK2-NOT: _ZTVN5test315basic_fstreamXXIcEE
+// CHECK2-NOT: @_ZTVN5test018stdio_sync_filebufIA1_iEE
+// CHECK2-NOT: @_ZTVN5test018stdio_sync_filebufIA2_iEE
+// CHECK2-NOT: @_ZN7PR100011SIiE3arr2E = linkonce_odr global [3 x i32]A
+
+// CHECK2-NOT: _ZTVN5test31SIiEE
+// CHECK2-NOT: _ZTSN5test31SIiEE
+
+// CHECK-LABEL: define linkonce_odr void @_ZN5test21CIiEC1Ev(%"class.test2::C"* %this) unnamed_addr
+// CHECK-LABEL: define linkonce_odr void @_ZN5test21CIiE6foobarIdEEvT_(
+// CHECK-LABEL: define available_externally void @_ZN5test21CIiE6zedbarEd(
+
+// CHECK-LABEL: define linkonce_odr void @_ZN7PR106662g1ENS_1SILi1EEE()
+// CHECK-LABEL: define linkonce_odr void @_ZN7PR106662g1ENS_1SILi2EEE()
+// CHECK-LABEL: define linkonce_odr void @_ZN7PR106662g1ENS_1SILi3EEE()
+// CHECK-LABEL: define linkonce_odr void @_ZN7PR106662g2ENS_1SILi1EEE()
+// CHECK-LABEL: define linkonce_odr void @_ZN7PR106662g2ENS_1SILi2EEE()
+// CHECK-LABEL: define linkonce_odr void @_ZN7PR106662g2ENS_1SILi3EEE()
+// CHECK: declare void @_ZN7PR106662h1ENS_1SILi1EEE()
+// CHECK: declare void @_ZN7PR106662h1ENS_1SILi2EEE()
+// CHECK: declare void @_ZN7PR106662h1ENS_1SILi3EEE()
+// CHECK: declare void @_ZN7PR106662h2ENS_1SILi1EEE()
+// CHECK: declare void @_ZN7PR106662h2ENS_1SILi2EEE()
+// CHECK: declare void @_ZN7PR106662h2ENS_1SILi3EEE()
+
+namespace test0 {
+ struct basic_streambuf {
+ virtual ~basic_streambuf();
+ };
+ template<typename _CharT >
+ struct stdio_sync_filebuf : public basic_streambuf {
+ virtual void xsgetn();
+ };
+
+ // This specialization is not a key function, so doesn't cause the vtable to
+ // be instantiated unless we're instantiating a class definition anyway.
+ template<> void stdio_sync_filebuf<int[1]>::xsgetn() {
+ }
+ template<> void stdio_sync_filebuf<int[2]>::xsgetn() {
+ }
+ template<> void stdio_sync_filebuf<int[3]>::xsgetn() {
+ }
+ template<> void stdio_sync_filebuf<int[4]>::xsgetn() {
+ }
+ extern template class stdio_sync_filebuf<int[2]>;
+
+ // These two both cause vtables to be emitted.
+ template class stdio_sync_filebuf<int[3]>;
+ stdio_sync_filebuf<int[4]> implicit_instantiation;
+}
+
+namespace test1 {
+ struct basic_streambuf {
+ virtual ~basic_streambuf();
+ };
+ template<typename _CharT >
+ struct stdio_sync_filebuf : public basic_streambuf {
+ virtual void xsgetn();
+ };
+
+ // Just a declaration should not force the vtable to be emitted.
+ template<> void stdio_sync_filebuf<wchar_t>::xsgetn();
+}
+
+namespace test2 {
+ template<typename T1>
+ class C {
+ public:
+ virtual ~C();
+ void zedbar(double) {
+ }
+ template<typename T2>
+ void foobar(T2 foo) {
+ }
+ };
+ extern template class C<int>;
+ void g() {
+ // The extern template declaration should not prevent us from producing
+ // the implicit constructor (test at the top).
+ C<int> a;
+
+ // or foobar(test at the top).
+ a.foobar(0.0);
+
+ // But it should prevent zebbar
+ // (test at the top).
+ a.zedbar(0.0);
+ }
+}
+
+namespace test3 {
+ template<typename T>
+ class basic_fstreamXX {
+ virtual void foo(){}
+ virtual void is_open() const { }
+ };
+
+ extern template class basic_fstreamXX<char>;
+ // This template instantiation should not cause us to produce a vtable.
+ // (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.
+// CHECK2-NOT: _ZN6PR85051AILi0EE1B1fEv
+template class A<0>;
+}
+
+// Ensure that when instantiating initializers for static data members to
+// complete their type in an unevaluated context, we *do* emit initializers with
+// side-effects, but *don't* emit initializers and variables which are otherwise
+// unused in the program.
+namespace PR10001 {
+ template <typename T> struct S {
+ static const int arr[];
+ static const int arr2[];
+ static const int x, y;
+ static int f();
+ };
+
+ extern int foo();
+ extern int kBar;
+
+ template <typename T> const int S<T>::arr[] = { 1, 2, foo() }; // possible side effects
+ template <typename T> const int S<T>::arr2[] = { 1, 2, kBar }; // no side effects
+ template <typename T> const int S<T>::x = sizeof(arr) / sizeof(arr[0]);
+ template <typename T> const int S<T>::y = sizeof(arr2) / sizeof(arr2[0]);
+ template <typename T> int S<T>::f() { return x + y; }
+
+ int x = S<int>::f();
+}
+
+// Ensure that definitions are emitted for all friend functions defined within
+// class templates. Order of declaration is extremely important here. Different
+// instantiations of the class happen at different points during the deferred
+// method body parsing and afterward. Those different points of instantiation
+// change the exact form the class template appears to have.
+namespace PR10666 {
+ template <int N> struct S {
+ void f1() { S<1> s; }
+ friend void g1(S s) {}
+ friend void h1(S s);
+ void f2() { S<2> s; }
+ friend void g2(S s) {}
+ friend void h2(S s);
+ void f3() { S<3> s; }
+ };
+ void test(S<1> s1, S<2> s2, S<3> s3) {
+ g1(s1); g1(s2); g1(s3);
+ g2(s1); g2(s2); g2(s3);
+ h1(s1); h1(s2); h1(s3);
+ h2(s1); h2(s2); h2(s3);
+ }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/template-linkage.cpp b/src/llvm-project/clang/test/CodeGenCXX/template-linkage.cpp
new file mode 100644
index 0000000..a84affa
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/template-linkage.cpp
@@ -0,0 +1,64 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+// CHECK: Outer5Inner{{.*}}localE6memberE = external global
+
+template<typename T> struct A {
+ virtual void f(T) { }
+ inline void g() { }
+};
+
+// Explicit instantiations have external linkage.
+
+// CHECK-LABEL: define weak_odr void @_ZN1AIiE1gEv(
+template void A<int>::g();
+
+// CHECK-LABEL: define weak_odr void @_ZN1AIfE1fEf(
+// CHECK-LABEL: define weak_odr void @_ZN1AIfE1gEv(
+// FIXME: This should also emit the vtable.
+template struct A<float>;
+
+// CHECK-LABEL: define weak_odr void @_Z1fIiEvT_
+template <typename T> void f(T) { }
+template void f<int>(int);
+
+// CHECK-LABEL: define weak_odr void @_Z1gIiEvT_
+template <typename T> inline void g(T) { }
+template void g<int>(int);
+
+template<typename T>
+struct X0 {
+ virtual ~X0() { }
+};
+
+template<typename T>
+struct X1 : X0<T> {
+ virtual void blarg();
+};
+
+template<typename T> void X1<T>::blarg() { }
+
+extern template struct X0<char>;
+extern template struct X1<char>;
+
+// CHECK-LABEL: define linkonce_odr void @_ZN2X1IcED1Ev(%struct.X1* %this) unnamed_addr
+void test_X1() {
+ X1<char> i1c;
+}
+
+namespace PR14825 {
+struct Outer {
+ template <typename T> struct Inner {
+ static int member;
+ };
+ template <typename T> void Get() {
+ int m = Inner<T>::member;
+ }
+};
+
+void test() {
+ struct local {};
+ Outer o;
+ typedef void (Outer::*mptr)();
+ mptr method = &Outer::Get<local>;
+}
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/template-static-var-defer.cpp b/src/llvm-project/clang/test/CodeGenCXX/template-static-var-defer.cpp
new file mode 100644
index 0000000..fe18c21
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/template-static-var-defer.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | not grep define
+// PR7415
+class X {
+ template <class Dummy> struct COMTypeInfo {
+ static const int kIID;
+ };
+ static const int& GetIID() {return COMTypeInfo<int>::kIID;}
+};
+template <class Dummy> const int X::COMTypeInfo<Dummy>::kIID = 10;
+
+
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/temporaries.cpp b/src/llvm-project/clang/test/CodeGenCXX/temporaries.cpp
new file mode 100644
index 0000000..294ff29
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/temporaries.cpp
@@ -0,0 +1,898 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -std=c++11 | FileCheck %s -check-prefixes=CHECK,NULL-INVALID,CHECK-CXX11
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -std=c++17 | FileCheck %s -check-prefixes=CHECK,NULL-INVALID,CHECK-CXX17
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -std=c++11 -fno-delete-null-pointer-checks | FileCheck %s -check-prefixes=CHECK,NULL-VALID,CHECK-CXX11
+
+namespace PR16263 {
+ const unsigned int n = 1234;
+ extern const int &r = (const int&)n;
+ // CHECK: @_ZGRN7PR162631rE_ = internal constant i32 1234,
+ // CHECK: @_ZN7PR162631rE = constant i32* @_ZGRN7PR162631rE_,
+
+ extern const int &s = reinterpret_cast<const int&>(n);
+ // CHECK: @_ZN7PR16263L1nE = internal constant i32 1234, align 4
+ // CHECK: @_ZN7PR162631sE = constant i32* @_ZN7PR16263L1nE, align 8
+
+ struct A { int n; };
+ struct B { int n; };
+ struct C : A, B {};
+ extern const A &&a = (A&&)(A&&)(C&&)(C{});
+ // CHECK: @_ZGRN7PR162631aE_ = internal global {{.*}} zeroinitializer,
+ // CHECK: @_ZN7PR162631aE = constant {{.*}} bitcast ({{.*}}* @_ZGRN7PR162631aE_ to
+
+ extern const int &&t = ((B&&)C{}).n;
+ // CHECK: @_ZGRN7PR162631tE_ = internal global {{.*}} zeroinitializer,
+ // CHECK: @_ZN7PR162631tE = constant i32* {{.*}}* @_ZGRN7PR162631tE_ {{.*}} 4
+
+ struct D { double d; C c; };
+ extern const int &&u = (123, static_cast<B&&>(0, ((D&&)D{}).*&D::c).n);
+ // CHECK: @_ZGRN7PR162631uE_ = internal global {{.*}} zeroinitializer
+ // CHECK: @_ZN7PR162631uE = constant i32* {{.*}} @_ZGRN7PR162631uE_ {{.*}} 12
+}
+
+namespace PR20227 {
+ struct A { ~A(); };
+ struct B { virtual ~B(); };
+ struct C : B {};
+
+ A &&a = dynamic_cast<A&&>(A{});
+ // CHECK: @_ZGRN7PR202271aE_ = internal global
+
+ B &&b = dynamic_cast<C&&>(dynamic_cast<B&&>(C{}));
+ // CHECK: @_ZGRN7PR202271bE_ = internal global
+
+ B &&c = static_cast<C&&>(static_cast<B&&>(C{}));
+ // CHECK: @_ZGRN7PR202271cE_ = internal global
+}
+
+namespace BraceInit {
+ typedef const int &CIR;
+ CIR x = CIR{3};
+ // CHECK-CXX11: @_ZGRN9BraceInit1xE_ = internal constant i32 3
+ // FIXME: This should still be emitted as 'constant' in C++17.
+ // CHECK-CXX17: @_ZGRN9BraceInit1xE_ = internal global i32 3
+ // CHECK: @_ZN9BraceInit1xE = constant i32* @_ZGRN9BraceInit1xE_
+}
+
+struct A {
+ A();
+ ~A();
+ void f();
+};
+
+void f1() {
+ // CHECK: call void @_ZN1AC1Ev
+ // CHECK: call void @_ZN1AD1Ev
+ (void)A();
+
+ // CHECK: call void @_ZN1AC1Ev
+ // CHECK: call void @_ZN1AD1Ev
+ A().f();
+}
+
+// Function calls
+struct B {
+ B();
+ ~B();
+};
+
+B g();
+
+void f2() {
+ // CHECK-NOT: call void @_ZN1BC1Ev
+ // CHECK: call void @_ZN1BD1Ev
+ (void)g();
+}
+
+// Member function calls
+struct C {
+ C();
+ ~C();
+
+ C f();
+};
+
+void f3() {
+ // CHECK: call void @_ZN1CC1Ev
+ // CHECK: call void @_ZN1CD1Ev
+ // CHECK: call void @_ZN1CD1Ev
+ C().f();
+}
+
+// Function call operator
+struct D {
+ D();
+ ~D();
+
+ D operator()();
+};
+
+void f4() {
+ // CHECK: call void @_ZN1DC1Ev
+ // CHECK: call void @_ZN1DD1Ev
+ // CHECK: call void @_ZN1DD1Ev
+ D()();
+}
+
+// Overloaded operators
+struct E {
+ E();
+ ~E();
+ E operator+(const E&);
+ E operator!();
+};
+
+void f5() {
+ // CHECK: call void @_ZN1EC1Ev
+ // CHECK: call void @_ZN1EC1Ev
+ // CHECK: call void @_ZN1ED1Ev
+ // CHECK: call void @_ZN1ED1Ev
+ // CHECK: call void @_ZN1ED1Ev
+ E() + E();
+
+ // CHECK: call void @_ZN1EC1Ev
+ // CHECK: call void @_ZN1ED1Ev
+ // CHECK: call void @_ZN1ED1Ev
+ !E();
+}
+
+struct F {
+ F();
+ ~F();
+ F& f();
+};
+
+void f6() {
+ // CHECK: call void @_ZN1FC1Ev
+ // CHECK: call void @_ZN1FD1Ev
+ F().f();
+}
+
+struct G {
+ G();
+ G(A);
+ ~G();
+ operator A();
+};
+
+void a(const A&);
+
+void f7() {
+ // CHECK: call void @_ZN1AC1Ev
+ // CHECK: call void @_Z1aRK1A
+ // CHECK: call void @_ZN1AD1Ev
+ a(A());
+
+ // CHECK: call void @_ZN1GC1Ev
+ // CHECK: call void @_ZN1Gcv1AEv
+ // CHECK: call void @_Z1aRK1A
+ // CHECK: call void @_ZN1AD1Ev
+ // CHECK: call void @_ZN1GD1Ev
+ a(G());
+}
+
+namespace PR5077 {
+
+struct A {
+ A();
+ ~A();
+ int f();
+};
+
+void f();
+int g(const A&);
+
+struct B {
+ int a1;
+ int a2;
+ B();
+ ~B();
+};
+
+B::B()
+ // CHECK: call void @_ZN6PR50771AC1Ev
+ // CHECK: call i32 @_ZN6PR50771A1fEv
+ // CHECK: call void @_ZN6PR50771AD1Ev
+ : a1(A().f())
+ // CHECK: call void @_ZN6PR50771AC1Ev
+ // CHECK: call i32 @_ZN6PR50771gERKNS_1AE
+ // CHECK: call void @_ZN6PR50771AD1Ev
+ , a2(g(A()))
+{
+ // CHECK: call void @_ZN6PR50771fEv
+ f();
+}
+
+}
+
+A f8() {
+ // CHECK: call void @_ZN1AC1Ev
+ // CHECK-NOT: call void @_ZN1AD1Ev
+ return A();
+ // CHECK: ret void
+}
+
+struct H {
+ H();
+ ~H();
+ H(const H&);
+};
+
+void f9(H h) {
+ // CHECK: call void @_ZN1HC1Ev
+ // CHECK: call void @_Z2f91H
+ // CHECK: call void @_ZN1HD1Ev
+ f9(H());
+
+ // CHECK: call void @_ZN1HC1ERKS_
+ // CHECK: call void @_Z2f91H
+ // CHECK: call void @_ZN1HD1Ev
+ f9(h);
+}
+
+void f10(const H&);
+
+void f11(H h) {
+ // CHECK: call void @_ZN1HC1Ev
+ // CHECK: call void @_Z3f10RK1H
+ // CHECK: call void @_ZN1HD1Ev
+ f10(H());
+
+ // CHECK: call void @_Z3f10RK1H
+ // CHECK-NOT: call void @_ZN1HD1Ev
+ // CHECK: ret void
+ f10(h);
+}
+
+// PR5808
+struct I {
+ I(const char *);
+ ~I();
+};
+
+// CHECK: _Z3f12v
+I f12() {
+ // CHECK: call void @_ZN1IC1EPKc
+ // CHECK-NOT: call void @_ZN1ID1Ev
+ // CHECK: ret void
+ return "Hello";
+}
+
+// PR5867
+namespace PR5867 {
+ struct S {
+ S();
+ S(const S &);
+ ~S();
+ };
+
+ void f(S, int);
+ // CHECK-LABEL: define void @_ZN6PR58671gEv
+ void g() {
+ // CHECK: call void @_ZN6PR58671SC1Ev
+ // CHECK-NEXT: call void @_ZN6PR58671fENS_1SEi
+ // CHECK-NEXT: call void @_ZN6PR58671SD1Ev
+ // CHECK-NEXT: ret void
+ (f)(S(), 0);
+ }
+
+ // CHECK-LABEL: define linkonce_odr void @_ZN6PR58672g2IiEEvT_
+ template<typename T>
+ void g2(T) {
+ // CHECK: call void @_ZN6PR58671SC1Ev
+ // CHECK-NEXT: call void @_ZN6PR58671fENS_1SEi
+ // CHECK-NEXT: call void @_ZN6PR58671SD1Ev
+ // CHECK-NEXT: ret void
+ (f)(S(), 0);
+ }
+
+ void h() {
+ g2(17);
+ }
+}
+
+// PR6199
+namespace PR6199 {
+ struct A { ~A(); };
+
+ struct B { operator A(); };
+
+ // CHECK-LABEL: define weak_odr void @_ZN6PR61992f2IiEENS_1AET_
+ template<typename T> A f2(T) {
+ B b;
+ // CHECK: call void @_ZN6PR61991BcvNS_1AEEv
+ // CHECK-NEXT: ret void
+ return b;
+ }
+
+ template A f2<int>(int);
+
+}
+
+namespace T12 {
+
+struct A {
+ A();
+ ~A();
+ int f();
+};
+
+int& f(int);
+
+// CHECK-LABEL: define void @_ZN3T121gEv
+void g() {
+ // CHECK: call void @_ZN3T121AC1Ev
+ // CHECK-NEXT: call i32 @_ZN3T121A1fEv(
+ // CHECK-NEXT: call dereferenceable({{[0-9]+}}) i32* @_ZN3T121fEi(
+ // CHECK-NEXT: call void @_ZN3T121AD1Ev(
+ int& i = f(A().f());
+}
+
+}
+
+namespace PR6648 {
+ struct B {
+ ~B();
+ };
+ B foo;
+ struct D;
+ D& zed(B);
+ void foobar() {
+ // NULL-INVALID: call nonnull %"struct.PR6648::D"* @_ZN6PR66483zedENS_1BE
+ // NULL-VALID: call %"struct.PR6648::D"* @_ZN6PR66483zedENS_1BE
+ zed(foo);
+ }
+}
+
+namespace UserConvertToValue {
+ struct X {
+ X(int);
+ X(const X&);
+ ~X();
+ };
+
+ void f(X);
+
+ // CHECK: void @_ZN18UserConvertToValue1gEv()
+ void g() {
+ // CHECK: call void @_ZN18UserConvertToValue1XC1Ei
+ // CHECK: call void @_ZN18UserConvertToValue1fENS_1XE
+ // CHECK: call void @_ZN18UserConvertToValue1XD1Ev
+ // CHECK: ret void
+ f(1);
+ }
+}
+
+namespace PR7556 {
+ struct A { ~A(); };
+ struct B { int i; ~B(); };
+ struct C { int C::*pm; ~C(); };
+ // CHECK-LABEL: define void @_ZN6PR75563fooEv()
+ void foo() {
+ // CHECK: call void @_ZN6PR75561AD1Ev
+ A();
+ // CHECK: call void @llvm.memset.p0i8.i64
+ // CHECK: call void @_ZN6PR75561BD1Ev
+ B();
+ // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
+ // CHECK: call void @_ZN6PR75561CD1Ev
+ C();
+ // 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-LABEL: 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-LABEL: 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]]* dereferenceable({{[0-9]+}}) [[X:%.*]])
+ A i = (c ? A() : x);
+
+ // CHECK: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[J]], [[A]]* dereferenceable({{[0-9]+}}) [[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]]* noalias 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]]* noalias sret
+ A test3(int v, A x) {
+ if (v < 5)
+ // CHECK: call void @_ZN7Elision1AC1Ev([[A]]* [[RET:%.*]])
+ // CHECK: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET]], [[A]]* dereferenceable({{[0-9]+}}) [[X:%.*]])
+ return (v < 0 ? A() : x);
+ else
+ // CHECK: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET]], [[A]]* dereferenceable({{[0-9]+}}) [[X]])
+ // CHECK: call void @_ZN7Elision1AC1Ev([[A]]* [[RET]])
+ return (v > 10 ? x : A());
+
+ // CHECK: ret void
+ }
+
+ // CHECK-LABEL: define void @_ZN7Elision5test4Ev()
+ void test4() {
+ // CHECK: [[X:%.*]] = alloca [[A]], align 8
+ // CHECK-NEXT: [[XS:%.*]] = alloca [2 x [[A]]], align 16
+
+ // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[X]])
+ A x;
+
+ // CHECK-NEXT: [[XS0:%.*]] = getelementptr inbounds [2 x [[A]]], [2 x [[A]]]* [[XS]], i64 0, i64 0
+ // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[XS0]])
+ // CHECK-NEXT: [[XS1:%.*]] = getelementptr inbounds [[A]], [[A]]* [[XS0]], i64 1
+ // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[XS1]], [[A]]* dereferenceable({{[0-9]+}}) [[X]])
+ A xs[] = { A(), x };
+
+ // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [2 x [[A]]], [2 x [[A]]]* [[XS]], i32 0, i32 0
+ // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]], [[A]]* [[BEGIN]], i64 2
+ // CHECK-NEXT: br label
+ // CHECK: [[AFTER:%.*]] = phi [[A]]*
+ // CHECK-NEXT: [[CUR:%.*]] = getelementptr inbounds [[A]], [[A]]* [[AFTER]], i64 -1
+ // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[CUR]])
+ // CHECK-NEXT: [[T0:%.*]] = icmp eq [[A]]* [[CUR]], [[BEGIN]]
+ // CHECK-NEXT: br i1 [[T0]],
+
+ // CHECK: call void @_ZN7Elision1AD1Ev([[A]]* [[X]])
+ }
+
+ // rdar://problem/8433352
+ // CHECK: define void @_ZN7Elision5test5Ev([[A]]* noalias 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]], [[B]]* [[BT0]], i32 0, i32 0
+ // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[AT0]], [[A]]* dereferenceable({{[0-9]+}}) [[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]], [[B]]* [[BT1]], i32 0, i32 0
+ // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[X]], [[A]]* dereferenceable({{[0-9]+}}) [[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]], [[B]]* [[BT2]], i32 0, i32 0
+ // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET:%.*]], [[A]]* dereferenceable({{[0-9]+}}) [[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]]*, [[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-LABEL: 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, i1* [[RCONS]]
+ // CHECK-NEXT: br i1
+ // CHECK: call void @_ZN6PR86231AD1Ev([[A]]* [[TMP]])
+ // CHECK-NEXT: br label
+ // CHECK: load i1, i1* [[LCONS]]
+ // CHECK-NEXT: br i1
+ // CHECK: call void @_ZN6PR86231AD1Ev([[A]]* [[TMP]])
+ // CHECK-NEXT: br label
+ // CHECK: ret void
+ b ? A(2) : A(3);
+ }
+}
+
+namespace PR11365 {
+ struct A { A(); ~A(); };
+
+ // CHECK-LABEL: define void @_ZN7PR113653fooEv(
+ void foo() {
+ // CHECK: [[BEGIN:%.*]] = getelementptr inbounds [3 x [[A:%.*]]], [3 x [[A:%.*]]]* {{.*}}, i32 0, i32 0
+ // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]], [[A]]* [[BEGIN]], i64 3
+ // CHECK-NEXT: br label
+
+ // CHECK: [[PHI:%.*]] = phi
+ // CHECK-NEXT: [[ELEM:%.*]] = getelementptr inbounds [[A]], [[A]]* [[PHI]], i64 -1
+ // CHECK-NEXT: call void @_ZN7PR113651AD1Ev([[A]]* [[ELEM]])
+ // CHECK-NEXT: icmp eq [[A]]* [[ELEM]], [[BEGIN]]
+ // CHECK-NEXT: br i1
+ (void) (A [3]) {};
+ }
+}
+
+namespace AssignmentOp {
+ struct A { ~A(); };
+ struct B { A operator=(const B&); };
+ struct C : B { B b1, b2; };
+ // CHECK-LABEL: define void @_ZN12AssignmentOp1fE
+ void f(C &c1, const C &c2) {
+ // CHECK: call {{.*}} @_ZN12AssignmentOp1CaSERKS0_(
+ c1 = c2;
+ }
+
+ // Ensure that each 'A' temporary is destroyed before the next subobject is
+ // copied.
+ // CHECK: define {{.*}} @_ZN12AssignmentOp1CaSERKS0_(
+ // CHECK: call {{.*}} @_ZN12AssignmentOp1BaSERKS
+ // CHECK: call {{.*}} @_ZN12AssignmentOp1AD1Ev(
+ // CHECK: call {{.*}} @_ZN12AssignmentOp1BaSERKS
+ // CHECK: call {{.*}} @_ZN12AssignmentOp1AD1Ev(
+ // CHECK: call {{.*}} @_ZN12AssignmentOp1BaSERKS
+ // CHECK: call {{.*}} @_ZN12AssignmentOp1AD1Ev(
+}
+
+namespace BindToSubobject {
+ struct A {
+ A();
+ ~A();
+ int a;
+ };
+
+ void f(), g();
+
+ // CHECK: call void @_ZN15BindToSubobject1AC1Ev({{.*}} @_ZGRN15BindToSubobject1aE_)
+ // CHECK: call i32 @__cxa_atexit({{.*}} bitcast ({{.*}} @_ZN15BindToSubobject1AD1Ev to void (i8*)*), i8* bitcast ({{.*}} @_ZGRN15BindToSubobject1aE_ to i8*), i8* @__dso_handle)
+ // CHECK: store i32* getelementptr inbounds ({{.*}} @_ZGRN15BindToSubobject1aE_, i32 0, i32 0), i32** @_ZN15BindToSubobject1aE, align 8
+ int &&a = A().a;
+
+ // CHECK: call void @_ZN15BindToSubobject1fEv()
+ // CHECK: call void @_ZN15BindToSubobject1AC1Ev({{.*}} @_ZGRN15BindToSubobject1bE_)
+ // CHECK: call i32 @__cxa_atexit({{.*}} bitcast ({{.*}} @_ZN15BindToSubobject1AD1Ev to void (i8*)*), i8* bitcast ({{.*}} @_ZGRN15BindToSubobject1bE_ to i8*), i8* @__dso_handle)
+ // CHECK: store i32* getelementptr inbounds ({{.*}} @_ZGRN15BindToSubobject1bE_, i32 0, i32 0), i32** @_ZN15BindToSubobject1bE, align 8
+ int &&b = (f(), A().a);
+
+ int A::*h();
+
+ // CHECK: call void @_ZN15BindToSubobject1fEv()
+ // CHECK: call void @_ZN15BindToSubobject1gEv()
+ // CHECK: call void @_ZN15BindToSubobject1AC1Ev({{.*}} @_ZGRN15BindToSubobject1cE_)
+ // CHECK: call i32 @__cxa_atexit({{.*}} bitcast ({{.*}} @_ZN15BindToSubobject1AD1Ev to void (i8*)*), i8* bitcast ({{.*}} @_ZGRN15BindToSubobject1cE_ to i8*), i8* @__dso_handle)
+ // CHECK: call {{.*}} @_ZN15BindToSubobject1hE
+ // CHECK: getelementptr
+ // CHECK: store i32* {{.*}}, i32** @_ZN15BindToSubobject1cE, align 8
+ int &&c = (f(), (g(), A().*h()));
+
+ struct B {
+ int padding;
+ A a;
+ };
+
+ // CHECK: call void @_ZN15BindToSubobject1BC1Ev({{.*}} @_ZGRN15BindToSubobject1dE_)
+ // CHECK: call i32 @__cxa_atexit({{.*}} bitcast ({{.*}} @_ZN15BindToSubobject1BD1Ev to void (i8*)*), i8* bitcast ({{.*}} @_ZGRN15BindToSubobject1dE_ to i8*), i8* @__dso_handle)
+ // CHECK: call {{.*}} @_ZN15BindToSubobject1hE
+ // CHECK: getelementptr {{.*}} getelementptr
+ // CHECK: store i32* {{.*}}, i32** @_ZN15BindToSubobject1dE, align 8
+ int &&d = (B().a).*h();
+}
+
+namespace Bitfield {
+ struct S { int a : 5; ~S(); };
+
+ // Do not lifetime extend the S() temporary here.
+ // CHECK: alloca
+ // CHECK: call {{.*}}memset
+ // CHECK: store i32 {{.*}}, i32* @_ZGRN8Bitfield1rE_
+ // CHECK: call void @_ZN8Bitfield1SD1
+ // CHECK: store i32* @_ZGRN8Bitfield1rE_, i32** @_ZN8Bitfield1rE, align 8
+ int &&r = S().a;
+}
+
+namespace Vector {
+ typedef __attribute__((vector_size(16))) int vi4a;
+ typedef __attribute__((ext_vector_type(4))) int vi4b;
+ struct S {
+ vi4a v;
+ vi4b w;
+ };
+ // CHECK: alloca
+ // CHECK: extractelement
+ // CHECK: store i32 {{.*}}, i32* @_ZGRN6Vector1rE_
+ // CHECK: store i32* @_ZGRN6Vector1rE_, i32** @_ZN6Vector1rE,
+ int &&r = S().v[1];
+
+ // CHECK: alloca
+ // CHECK: extractelement
+ // CHECK: store i32 {{.*}}, i32* @_ZGRN6Vector1sE_
+ // CHECK: store i32* @_ZGRN6Vector1sE_, i32** @_ZN6Vector1sE,
+ int &&s = S().w[1];
+ // FIXME PR16204: The following code leads to an assertion in Sema.
+ //int &&s = S().w.y;
+}
+
+namespace ImplicitTemporaryCleanup {
+ struct A { A(int); ~A(); };
+ void g();
+
+ // CHECK-LABEL: define void @_ZN24ImplicitTemporaryCleanup1fEv(
+ void f() {
+ // CHECK: call {{.*}} @_ZN24ImplicitTemporaryCleanup1AC1Ei(
+ A &&a = 0;
+
+ // CHECK: call {{.*}} @_ZN24ImplicitTemporaryCleanup1gEv(
+ g();
+
+ // CHECK: call {{.*}} @_ZN24ImplicitTemporaryCleanup1AD1Ev(
+ }
+}
+
+namespace MultipleExtension {
+ struct A { A(); ~A(); };
+ struct B { B(); ~B(); };
+ struct C { C(); ~C(); };
+ struct D { D(); ~D(); int n; C c; };
+ struct E { const A &a; B b; const C &c; ~E(); };
+
+ E &&e1 = { A(), B(), D().c };
+
+ // CHECK: call void @_ZN17MultipleExtension1AC1Ev({{.*}} @[[TEMPA:_ZGRN17MultipleExtension2e1E.*]])
+ // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1AD1Ev {{.*}} @[[TEMPA]]
+ // CHECK: store {{.*}} @[[TEMPA]], {{.*}} getelementptr inbounds ({{.*}} @[[TEMPE:_ZGRN17MultipleExtension2e1E.*]], i32 0, i32 0)
+
+ // CHECK: call void @_ZN17MultipleExtension1BC1Ev({{.*}} getelementptr inbounds ({{.*}} @[[TEMPE]], i32 0, i32 1))
+
+ // CHECK: call void @_ZN17MultipleExtension1DC1Ev({{.*}} @[[TEMPD:_ZGRN17MultipleExtension2e1E.*]])
+ // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1DD1Ev {{.*}} @[[TEMPD]]
+ // CHECK: store {{.*}} @[[TEMPD]], {{.*}} getelementptr inbounds ({{.*}} @[[TEMPE]], i32 0, i32 2)
+ // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1ED1Ev {{.*}} @[[TEMPE]]
+ // CHECK: store {{.*}} @[[TEMPE]], %"struct.MultipleExtension::E"** @_ZN17MultipleExtension2e1E, align 8
+
+ E e2 = { A(), B(), D().c };
+
+ // CHECK: call void @_ZN17MultipleExtension1AC1Ev({{.*}} @[[TEMPA:_ZGRN17MultipleExtension2e2E.*]])
+ // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1AD1Ev {{.*}} @[[TEMPA]]
+ // CHECK: store {{.*}} @[[TEMPA]], {{.*}} getelementptr inbounds ({{.*}} @[[E:_ZN17MultipleExtension2e2E]], i32 0, i32 0)
+
+ // CHECK: call void @_ZN17MultipleExtension1BC1Ev({{.*}} getelementptr inbounds ({{.*}} @[[E]], i32 0, i32 1))
+
+ // CHECK: call void @_ZN17MultipleExtension1DC1Ev({{.*}} @[[TEMPD:_ZGRN17MultipleExtension2e2E.*]])
+ // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1DD1Ev {{.*}} @[[TEMPD]]
+ // CHECK: store {{.*}} @[[TEMPD]], {{.*}} getelementptr inbounds ({{.*}} @[[E]], i32 0, i32 2)
+ // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1ED1Ev {{.*}} @[[E]]
+
+
+ void g();
+ // CHECK: define void @[[NS:_ZN17MultipleExtension]]1fEv(
+ void f() {
+ E &&e1 = { A(), B(), D().c };
+ // CHECK: %[[TEMPE1_A:.*]] = getelementptr inbounds {{.*}} %[[TEMPE1:.*]], i32 0, i32 0
+ // CHECK: call void @[[NS]]1AC1Ev({{.*}} %[[TEMPA1:.*]])
+ // CHECK: store {{.*}} %[[TEMPA1]], {{.*}} %[[TEMPE1_A]]
+ // CHECK: %[[TEMPE1_B:.*]] = getelementptr inbounds {{.*}} %[[TEMPE1]], i32 0, i32 1
+ // CHECK: call void @[[NS]]1BC1Ev({{.*}} %[[TEMPE1_B]])
+ // CHECK: %[[TEMPE1_C:.*]] = getelementptr inbounds {{.*}} %[[TEMPE1]], i32 0, i32 2
+ // CHECK: call void @[[NS]]1DC1Ev({{.*}} %[[TEMPD1:.*]])
+ // CHECK: %[[TEMPD1_C:.*]] = getelementptr inbounds {{.*}} %[[TEMPD1]], i32 0, i32 1
+ // CHECK: store {{.*}} %[[TEMPD1_C]], {{.*}} %[[TEMPE1_C]]
+ // CHECK: store {{.*}} %[[TEMPE1]], {{.*}} %[[E1:.*]]
+
+ g();
+ // CHECK: call void @[[NS]]1gEv()
+
+ E e2 = { A(), B(), D().c };
+ // CHECK: %[[TEMPE2_A:.*]] = getelementptr inbounds {{.*}} %[[E2:.*]], i32 0, i32 0
+ // CHECK: call void @[[NS]]1AC1Ev({{.*}} %[[TEMPA2:.*]])
+ // CHECK: store {{.*}} %[[TEMPA2]], {{.*}} %[[TEMPE2_A]]
+ // CHECK: %[[TEMPE2_B:.*]] = getelementptr inbounds {{.*}} %[[E2]], i32 0, i32 1
+ // CHECK: call void @[[NS]]1BC1Ev({{.*}} %[[TEMPE2_B]])
+ // CHECK: %[[TEMPE2_C:.*]] = getelementptr inbounds {{.*}} %[[E2]], i32 0, i32 2
+ // CHECK: call void @[[NS]]1DC1Ev({{.*}} %[[TEMPD2:.*]])
+ // CHECK: %[[TEMPD2_C:.*]] = getelementptr inbounds {{.*}} %[[TEMPD2]], i32 0, i32 1
+ // CHECK: store {{.*}} %[[TEMPD2_C]], {{.*}}* %[[TEMPE2_C]]
+
+ g();
+ // CHECK: call void @[[NS]]1gEv()
+
+ // CHECK: call void @[[NS]]1ED1Ev({{.*}} %[[E2]])
+ // CHECK: call void @[[NS]]1DD1Ev({{.*}} %[[TEMPD2]])
+ // CHECK: call void @[[NS]]1AD1Ev({{.*}} %[[TEMPA2]])
+ // CHECK: call void @[[NS]]1ED1Ev({{.*}} %[[TEMPE1]])
+ // CHECK: call void @[[NS]]1DD1Ev({{.*}} %[[TEMPD1]])
+ // CHECK: call void @[[NS]]1AD1Ev({{.*}} %[[TEMPA1]])
+ }
+}
+
+namespace ArrayAccess {
+ struct A { A(int); ~A(); };
+ void g();
+ void f() {
+ using T = A[3];
+
+ // CHECK: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 1
+ // CHECK-NOT: @_ZN11ArrayAccess1AD
+ // CHECK: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 2
+ // CHECK-NOT: @_ZN11ArrayAccess1AD
+ // CHECK: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 3
+ // CHECK-NOT: @_ZN11ArrayAccess1AD
+ A &&a = T{1, 2, 3}[1];
+
+ // CHECK: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 4
+ // CHECK-NOT: @_ZN11ArrayAccess1AD
+ // CHECK: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 5
+ // CHECK-NOT: @_ZN11ArrayAccess1AD
+ // CHECK: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 6
+ // CHECK-NOT: @_ZN11ArrayAccess1AD
+ A &&b = 2[T{4, 5, 6}];
+
+ // CHECK: call void @_ZN11ArrayAccess1gEv(
+ g();
+
+ // CHECK: call void @_ZN11ArrayAccess1AD
+ // CHECK: call void @_ZN11ArrayAccess1AD
+ }
+}
+
+namespace PR14130 {
+ struct S { S(int); };
+ struct U { S &&s; };
+ U v { { 0 } };
+ // CHECK: call void @_ZN7PR141301SC1Ei({{.*}} @_ZGRN7PR141301vE_, i32 0)
+ // CHECK: store {{.*}} @_ZGRN7PR141301vE_, {{.*}} @_ZN7PR141301vE
+}
+
+namespace Conditional {
+ struct A {};
+ struct B : A { B(); ~B(); };
+ struct C : A { C(); ~C(); };
+
+ void g();
+
+ // CHECK-LABEL: define {{.*}} @_ZN11Conditional1fEb(
+ void f(bool b) {
+ // CHECK: store i1 false, i1* %[[CLEANUP_B:.*]],
+ // CHECK: store i1 false, i1* %[[CLEANUP_C:.*]],
+ // CHECK: br i1
+ //
+ // CHECK: call {{.*}} @_ZN11Conditional1BC1Ev(
+ // CHECK: store i1 true, i1* %[[CLEANUP_B]],
+ // CHECK: br label
+ //
+ // CHECK: call {{.*}} @_ZN11Conditional1CC1Ev(
+ // CHECK: store i1 true, i1* %[[CLEANUP_C]],
+ // CHECK: br label
+ A &&r = b ? static_cast<A&&>(B()) : static_cast<A&&>(C());
+
+ // CHECK: call {{.*}} @_ZN11Conditional1gEv(
+ g();
+
+ // CHECK: load {{.*}} %[[CLEANUP_C]]
+ // CHECK: br i1
+ // CHECK: call {{.*}} @_ZN11Conditional1CD1Ev(
+ // CHECK: br label
+
+ // CHECK: load {{.*}} %[[CLEANUP_B]]
+ // CHECK: br i1
+ // CHECK: call {{.*}} @_ZN11Conditional1BD1Ev(
+ // CHECK: br label
+ }
+
+ struct D { A &&a; };
+ // CHECK-LABEL: define {{.*}} @_ZN11Conditional10f_indirectEb(
+ void f_indirect(bool b) {
+ // CHECK: store i1 false, i1* %[[CLEANUP_B:.*]],
+ // CHECK: store i1 false, i1* %[[CLEANUP_C:.*]],
+ // CHECK: br i1
+ //
+ // CHECK: call {{.*}} @_ZN11Conditional1BC1Ev(
+ // CHECK: store i1 true, i1* %[[CLEANUP_B]],
+ // CHECK: br label
+ //
+ // CHECK: call {{.*}} @_ZN11Conditional1CC1Ev(
+ // CHECK: store i1 true, i1* %[[CLEANUP_C]],
+ // CHECK: br label
+ D d = b ? D{B()} : D{C()};
+
+ // In C++17, the expression D{...} directly initializes the 'd' object, so
+ // lifetime-extending the temporaries to the lifetime of the D object
+ // extends them past the call to g().
+ //
+ // In C++14 and before, D is move-constructed from the result of the
+ // conditional expression, so no lifetime extension occurs.
+
+ // CHECK-CXX17: call {{.*}} @_ZN11Conditional1gEv(
+
+ // CHECK: load {{.*}} %[[CLEANUP_C]]
+ // CHECK: br i1
+ // CHECK: call {{.*}} @_ZN11Conditional1CD1Ev(
+ // CHECK: br label
+
+ // CHECK: load {{.*}} %[[CLEANUP_B]]
+ // CHECK: br i1
+ // CHECK: call {{.*}} @_ZN11Conditional1BD1Ev(
+ // CHECK: br label
+
+ // CHECK-CXX11: call {{.*}} @_ZN11Conditional1gEv(
+ g();
+ }
+
+ extern bool b;
+ // CHECK: load {{.*}} @_ZN11Conditional1b
+ // CHECK: br i1
+ //
+ // CHECK: call {{.*}} @_ZN11Conditional1BC1Ev({{.*}} @_ZGRN11Conditional1rE_)
+ // CHECK: call {{.*}} @__cxa_atexit({{.*}} @_ZN11Conditional1BD1Ev {{.*}} @_ZGRN11Conditional1rE_,
+ // CHECK: br label
+ //
+ // CHECK: call {{.*}} @_ZN11Conditional1CC1Ev({{.*}} @_ZGRN11Conditional1rE0_)
+ // CHECK: call {{.*}} @__cxa_atexit({{.*}} @_ZN11Conditional1CD1Ev {{.*}} @_ZGRN11Conditional1rE0_,
+ // CHECK: br label
+ A &&r = b ? static_cast<A&&>(B()) : static_cast<A&&>(C());
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/thiscall-struct-return.cpp b/src/llvm-project/clang/test/CodeGenCXX/thiscall-struct-return.cpp
new file mode 100644
index 0000000..a6be5aa
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/thiscall-struct-return.cpp
@@ -0,0 +1,41 @@
+// For MSVC ABI compatibility, all structures returned by value using the
+// thiscall calling convention must use the hidden parameter.
+//
+// RUN: %clang_cc1 -triple i386-PC-Win32 %s -fms-compatibility -emit-llvm -o - | FileCheck %s
+
+// This structure would normally be returned via EAX
+struct S {
+ int i;
+};
+
+// This structure would normally be returned via EAX/EDX
+struct M {
+ int i;
+ int j;
+};
+
+class C {
+public:
+ C() {}
+
+ struct S __attribute__((thiscall)) Small() const {
+ struct S s = { 0 };
+ return s;
+ }
+
+ struct M __attribute__((thiscall)) Medium() const {
+ struct M m = { 0 };
+ return m;
+ }
+};
+
+// CHECK-LABEL: define void @_Z4testv()
+void test( void ) {
+// CHECK: call void @_ZN1CC1Ev(%class.C* [[C:%.+]])
+ C c;
+
+// CHECK: call x86_thiscallcc void @_ZNK1C5SmallEv(%struct.S* sret %{{.+}}, %class.C* [[C]])
+ (void)c.Small();
+// CHECK: call x86_thiscallcc void @_ZNK1C6MediumEv(%struct.M* sret %{{.+}}, %class.C* [[C]])
+ (void)c.Medium();
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/threadsafe-statics-exceptions.cpp b/src/llvm-project/clang/test/CodeGenCXX/threadsafe-statics-exceptions.cpp
new file mode 100644
index 0000000..41325fa
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/threadsafe-statics-exceptions.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -emit-llvm -o - -fcxx-exceptions -fexceptions -triple x86_64-apple-darwin10 %s | FileCheck %s
+
+struct X {
+ X();
+ ~X();
+};
+
+struct Y { };
+
+// CHECK-LABEL: define void @_Z1fv
+// CHECK-SAME: personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+void f() {
+ // CHECK: call i32 @__cxa_guard_acquire(i64* @_ZGVZ1fvE1x)
+ // CHECK: invoke void @_ZN1XC1Ev
+ // CHECK: call i32 @__cxa_atexit
+ // CHECK-NEXT: call void @__cxa_guard_release(i64* @_ZGVZ1fvE1x)
+ // CHECK: br
+ static X x;
+
+ // CHECK: call i8* @__cxa_allocate_exception
+ // CHECK: call void @__cxa_throw
+ throw Y();
+
+ // Finally, the landing pad.
+ // CHECK: landingpad { i8*, i32 }
+ // CHECK: cleanup
+ // CHECK: call void @__cxa_guard_abort(i64* @_ZGVZ1fvE1x)
+ // CHECK: resume { i8*, i32 }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/threadsafe-statics.cpp b/src/llvm-project/clang/test/CodeGenCXX/threadsafe-statics.cpp
new file mode 100644
index 0000000..7cb7003f
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/threadsafe-statics.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -emit-llvm -triple=x86_64-apple-darwin10 -o - %s | FileCheck -check-prefix=WITH-TSS %s
+// RUN: %clang_cc1 -emit-llvm -triple=x86_64-apple-darwin10 -o - %s -fno-threadsafe-statics | FileCheck -check-prefix=NO-TSS %s
+
+int f();
+
+// WITH-TSS: @_ZZ1gvE1a = internal global i32 0, align 4
+// WITH-TSS: @_ZGVZ1gvE1a = internal global i64 0
+
+// WITH-TSS: define void @_Z1gv() [[NUW:#[0-9]+]]
+// WITH-TSS: call i32 @__cxa_guard_acquire
+// WITH-TSS: call void @__cxa_guard_release
+// WITH-TSS: ret void
+void g() {
+ static int a = f();
+}
+
+// NO-TSS: @_ZZ1gvE1a = internal global i32 0, align 4
+// NO-TSS: @_ZGVZ1gvE1a = internal global i8 0
+
+// NO-TSS: define void @_Z1gv() [[NUW:#[0-9]+]]
+// NO-TSS-NOT: call i32 @__cxa_guard_acquire
+// NO-TSS-NOT: call void @__cxa_guard_release
+// NO-TSS: ret void
+
+// WITH-TSS: attributes [[NUW]] = { noinline nounwind{{.*}} }
+
+// NO-TSS: attributes [[NUW]] = { noinline nounwind{{.*}} }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/throw-expression-cleanup.cpp b/src/llvm-project/clang/test/CodeGenCXX/throw-expression-cleanup.cpp
new file mode 100644
index 0000000..9944e16
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/throw-expression-cleanup.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 %s -triple x86_64-none-linux-gnu -emit-llvm -fcxx-exceptions -fexceptions -std=c++11 -o - | FileCheck %s
+// PR13359
+
+struct X {
+ ~X();
+};
+struct Error {
+ Error(const X&) noexcept;
+};
+
+void f() {
+ try {
+ throw Error(X());
+ } catch (...) { }
+}
+
+// CHECK-LABEL: define void @_Z1fv
+// CHECK: call void @_ZN5ErrorC1ERK1X
+// CHECK: invoke void @__cxa_throw
+// CHECK: landingpad
+// CHECK: call void @_ZN1XD1Ev
+// CHECK-NOT: __cxa_free_exception
diff --git a/src/llvm-project/clang/test/CodeGenCXX/throw-expression-dtor.cpp b/src/llvm-project/clang/test/CodeGenCXX/throw-expression-dtor.cpp
new file mode 100644
index 0000000..b883b85
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/throw-expression-dtor.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 %s -emit-llvm-only -verify -triple %itanium_abi_triple -fcxx-exceptions -fexceptions
+// expected-no-diagnostics
+// PR7281
+
+class A {
+public:
+ ~A();
+};
+class B : public A {
+ void ice_throw();
+};
+void B::ice_throw() {
+ throw *this;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/throw-expressions.cpp b/src/llvm-project/clang/test/CodeGenCXX/throw-expressions.cpp
new file mode 100644
index 0000000..3fe2038
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/throw-expressions.cpp
@@ -0,0 +1,114 @@
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -Wno-unreachable-code -Werror -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s
+
+int val = 42;
+int& test1() {
+ return throw val, val;
+}
+
+int test2() {
+ return val ? throw val : val;
+}
+
+// rdar://problem/8608801
+void test3() {
+ throw false;
+}
+
+// PR10582
+int test4() {
+ return 1 ? throw val : val;
+}
+
+// PR15923
+int test5(bool x, bool y, int z) {
+ return (x ? throw 1 : y) ? z : throw 2;
+}
+// CHECK-LABEL: define i32 @_Z5test5bbi(
+// CHECK: br i1
+//
+// x.true:
+// CHECK: call void @__cxa_throw(
+// CHECK-NEXT: unreachable
+//
+// x.false:
+// CHECK: br i1
+//
+// y.true:
+// CHECK: load i32, i32*
+// CHECK: br label
+//
+// y.false:
+// CHECK: call void @__cxa_throw(
+// CHECK-NEXT: unreachable
+//
+// end:
+// CHECK: ret i32
+
+int test6(bool x, bool y, int z) {
+ return (x ? throw 1 : y) ? z : (throw 2);
+}
+// CHECK-LABEL: define i32 @_Z5test6bbi(
+// CHECK: br i1
+//
+// x.true:
+// CHECK: call void @__cxa_throw(
+// CHECK-NEXT: unreachable
+//
+// x.false:
+// CHECK: br i1
+//
+// y.true:
+// CHECK: load i32, i32*
+// CHECK: br label
+//
+// y.false:
+// CHECK: call void @__cxa_throw(
+// CHECK-NEXT: unreachable
+//
+// end:
+// CHECK: ret i32
+
+namespace DR1560 {
+ struct A {
+ ~A();
+ };
+ extern bool b;
+ A get();
+ // CHECK-LABEL: @_ZN6DR15601bE
+ const A &r = b ? get() : throw 0;
+ // CHECK-NOT: call {{.*}}@_ZN6DR15601AD1Ev
+ // CHECK: call {{.*}} @__cxa_atexit({{.*}} @_ZN6DR15601AD1Ev {{.*}} @_ZGRN6DR15601rE
+ // CHECK-NOT: call {{.*}}@_ZN6DR15601AD1Ev
+}
+
+// CHECK-LABEL: define void @_Z5test7b(
+void test7(bool cond) {
+ // CHECK: br i1
+ //
+ // x.true:
+ // CHECK: call void @__cxa_throw(
+ // CHECK-NEXT: unreachable
+ //
+ // x.false:
+ // CHECK: br label
+ //
+ // end:
+ // CHECK: ret void
+ cond ? throw test7 : val;
+}
+
+// CHECK-LABEL: define dereferenceable(4) i32* @_Z5test8b(
+int &test8(bool cond) {
+ // CHECK: br i1
+ //
+ // x.true:
+ // CHECK: br label
+ //
+ // x.false:
+ // CHECK: call void @__cxa_throw(
+ // CHECK-NEXT: unreachable
+ //
+ // end:
+ // CHECK: ret i32* @val
+ return cond ? val : ((throw "foo"));
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/thunk-linkonce-odr.cpp b/src/llvm-project/clang/test/CodeGenCXX/thunk-linkonce-odr.cpp
new file mode 100644
index 0000000..82f2148
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/thunk-linkonce-odr.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 %s -triple i386-unknown-unknown -emit-llvm -o - | FileCheck %s
+// <rdar://problem/7929157> & <rdar://problem/8104369>
+
+struct A {
+ virtual int f() { return 1; }
+};
+
+struct B {
+ virtual int f() { return 2; }
+};
+
+struct C : A, B {
+ virtual int f() { return 3; }
+};
+
+struct D : C {
+ virtual int f() { return 4; }
+};
+
+static int f(D* d) {
+ B* b = d;
+ return b->f();
+};
+
+int g() {
+ D d;
+ return f(&d);
+}
+
+// Thunks should be marked as "linkonce ODR" not "weak".
+//
+// CHECK: define linkonce_odr i32 @_ZThn{{[48]}}_N1D1fEv
+// CHECK: define linkonce_odr i32 @_ZThn{{[48]}}_N1C1fEv
diff --git a/src/llvm-project/clang/test/CodeGenCXX/thunk-returning-memptr.cpp b/src/llvm-project/clang/test/CodeGenCXX/thunk-returning-memptr.cpp
new file mode 100644
index 0000000..0b7870c
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/thunk-returning-memptr.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -triple=i686 -emit-llvm -o - %s | FileCheck %s
+
+
+struct X;
+typedef void (X::*memptr)();
+
+struct A {
+ virtual memptr f();
+};
+
+struct B {
+ virtual memptr f();
+};
+
+struct C : A, B {
+ C();
+ memptr f() override __attribute__((noinline)) { return nullptr; };
+};
+
+C::C() {}
+
+// Make sure the member pointer is returned from the thunk via the return slot.
+// Because of the tail call, the return value cannot be copied into a local
+// alloca. (PR39901)
+
+// CHECK-LABEL: define linkonce_odr void @_ZThn4_N1C1fEv({ i32, i32 }* noalias sret %agg.result, %struct.C* %this)
+// CHECK: tail call void @_ZN1C1fEv({ i32, i32 }* sret %agg.result
diff --git a/src/llvm-project/clang/test/CodeGenCXX/thunk-use-after-free.cpp b/src/llvm-project/clang/test/CodeGenCXX/thunk-use-after-free.cpp
new file mode 100644
index 0000000..14f2356
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/thunk-use-after-free.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -emit-llvm-only -triple %itanium_abi_triple -O1 %s
+// This used to crash under asan and valgrind.
+// PR12284
+
+template < typename _Tp > struct new_allocator
+{
+ typedef _Tp *pointer;
+ template < typename > struct rebind {
+ typedef new_allocator other;
+ };
+};
+template < typename _Tp > struct allocator:new_allocator < _Tp > {
+};
+template < typename _Tp, typename _Alloc > struct _Vector_base {
+ typedef typename _Alloc::template rebind < _Tp >::other _Tp_alloc_type;
+ struct _Vector_impl {
+ typename _Tp_alloc_type::pointer _M_end_of_storage;
+ };
+ _Vector_base () {
+ foo((int *) this->_M_impl._M_end_of_storage);
+ }
+ void foo(int *);
+ _Vector_impl _M_impl;
+};
+template < typename _Tp, typename _Alloc =
+allocator < _Tp > >struct vector:_Vector_base < _Tp, _Alloc > { };
+
+
+template < class T> struct HHH {};
+struct DDD { int x_;};
+struct Data;
+struct X1;
+struct CCC:DDD { virtual void xxx (HHH < X1 >); };
+template < class SSS > struct EEE:vector < HHH < SSS > > { };
+template < class SSS, class = EEE < SSS > >class FFF { };
+template < class SSS, class GGG = EEE < SSS > >class AAA:FFF <GGG> { };
+class BBB:virtual CCC {
+ void xxx (HHH < X1 >);
+ vector < HHH < X1 > >aaa;
+};
+class ZZZ:AAA < Data >, BBB { virtual ZZZ *ppp () ; };
+ZZZ * ZZZ::ppp () { return new ZZZ; }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/thunks-available-externally.cpp b/src/llvm-project/clang/test/CodeGenCXX/thunks-available-externally.cpp
new file mode 100644
index 0000000..01e4947
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/thunks-available-externally.cpp
@@ -0,0 +1,79 @@
+// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -emit-llvm-only -O3
+
+// 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();
+}
+
+}
+
+// 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/src/llvm-project/clang/test/CodeGenCXX/thunks.cpp b/src/llvm-project/clang/test/CodeGenCXX/thunks.cpp
new file mode 100644
index 0000000..b4a0f90
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/thunks.cpp
@@ -0,0 +1,405 @@
+// RUN: %clang_cc1 %s -triple=x86_64-pc-linux-gnu -munwind-tables -emit-llvm -o - | FileCheck --check-prefix=CHECK --check-prefix=CHECK-NONOPT %s
+// RUN: %clang_cc1 %s -triple=x86_64-pc-linux-gnu -munwind-tables -emit-llvm -o - -O1 -disable-llvm-passes | FileCheck --check-prefix=CHECK --check-prefix=CHECK-OPT %s
+
+namespace Test1 {
+
+// Check that we emit a non-virtual thunk for C::f.
+
+struct A {
+ virtual void f();
+};
+
+struct B {
+ virtual void f();
+};
+
+struct C : A, B {
+ virtual void c();
+
+ virtual void f();
+};
+
+// CHECK-LABEL: define void @_ZThn8_N5Test11C1fEv(
+void C::f() { }
+
+}
+
+namespace Test2 {
+
+// Check that we emit a thunk for B::f since it's overriding a virtual base.
+
+struct A {
+ virtual void f();
+};
+
+struct B : virtual A {
+ virtual void b();
+ virtual void f();
+};
+
+// CHECK-LABEL: define void @_ZTv0_n24_N5Test21B1fEv(
+void B::f() { }
+
+}
+
+namespace Test3 {
+
+// Check that we emit a covariant thunk for B::f.
+
+struct V1 { };
+struct V2 : virtual V1 { };
+
+struct A {
+ virtual V1 *f();
+};
+
+struct B : A {
+ virtual void b();
+
+ virtual V2 *f();
+};
+
+// CHECK: define %{{.*}}* @_ZTch0_v0_n24_N5Test31B1fEv(
+V2 *B::f() { return 0; }
+
+}
+
+namespace Test4 {
+
+// Check that the thunk for 'C::f' has the same visibility as the function itself.
+
+struct A {
+ virtual void f();
+};
+
+struct B {
+ virtual void f();
+};
+
+struct __attribute__((visibility("protected"))) C : A, B {
+ virtual void c();
+
+ virtual void f();
+};
+
+// CHECK-LABEL: define protected void @_ZThn8_N5Test41C1fEv(
+void C::f() { }
+
+}
+
+// Check that the thunk gets internal linkage.
+namespace Test4B {
+ struct A {
+ virtual void 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();
+ }
+}
+
+namespace Test5 {
+
+// Check that the thunk for 'B::f' gets the same linkage as the function itself.
+struct A {
+ virtual void f();
+};
+
+struct B : virtual A {
+ virtual void f() { }
+};
+
+void f(B b) {
+ b.f();
+}
+}
+
+namespace Test6 {
+ struct X {
+ X();
+ X(const X&);
+ X &operator=(const X&);
+ ~X();
+ };
+
+ struct P {
+ P();
+ P(const P&);
+ ~P();
+ X first;
+ X second;
+ };
+
+ P getP();
+
+ struct Base1 {
+ int i;
+
+ virtual X f() { return X(); }
+ };
+
+ struct Base2 {
+ float real;
+
+ virtual X f() { return X(); }
+ };
+
+ struct Thunks : Base1, Base2 {
+ long l;
+
+ virtual X f();
+ };
+
+ // CHECK-LABEL: define void @_ZThn16_N5Test66Thunks1fEv
+ // CHECK-NOT: memcpy
+ // CHECK: {{call void @_ZN5Test66Thunks1fEv.*sret}}
+ // CHECK: ret void
+ X Thunks::f() { return X(); }
+}
+
+namespace Test7 {
+ // PR7188
+ struct X {
+ X();
+ X(const X&);
+ X &operator=(const X&);
+ ~X();
+ };
+
+ struct Small { short s; };
+ struct Large {
+ char array[1024];
+ };
+
+ class A {
+ protected:
+ virtual void foo() = 0;
+ };
+
+ class B : public A {
+ protected:
+ virtual void bar() = 0;
+ };
+
+ class C : public A {
+ protected:
+ virtual void baz(X, X&, _Complex float, Small, Small&, Large) = 0;
+ };
+
+ class D : public B,
+ public C {
+
+ void foo() {}
+ void bar() {}
+ void baz(X, X&, _Complex float, Small, Small&, Large);
+ };
+
+ void D::baz(X, X&, _Complex float, Small, Small&, Large) { }
+
+ // CHECK-LABEL: define void @_ZThn8_N5Test71D3bazENS_1XERS1_CfNS_5SmallERS4_NS_5LargeE(
+ // CHECK-NOT: memcpy
+ // CHECK: ret void
+ void testD() { D d; }
+}
+
+namespace Test8 {
+ struct NonPOD { ~NonPOD(); int x, y, z; };
+ struct A { virtual void foo(); };
+ struct B { virtual void bar(NonPOD); };
+ struct C : A, B { virtual void bar(NonPOD); static void helper(NonPOD); };
+
+ // CHECK: define void @_ZN5Test81C6helperENS_6NonPODE([[NONPODTYPE:%.*]]*
+ void C::helper(NonPOD var) {}
+
+ // CHECK-LABEL: define void @_ZThn8_N5Test81C3barENS_6NonPODE(
+ // CHECK-NOT: load [[NONPODTYPE]], [[NONPODTYPE]]*
+ // CHECK-NOT: memcpy
+ // CHECK: ret void
+ void C::bar(NonPOD var) {}
+}
+
+// PR7241: Emitting thunks for a method shouldn't require the vtable for
+// that class to be emitted.
+namespace Test9 {
+ struct A { virtual ~A() { } };
+ struct B : A { virtual void test() const {} };
+ struct C : B { C(); ~C(); };
+ struct D : C { D() {} };
+ void test() {
+ D d;
+ }
+}
+
+namespace Test10 {
+ struct A { virtual void foo(); };
+ struct B { virtual void foo(); };
+ struct C : A, B { void foo() {} };
+
+ // Test later.
+ void test() {
+ C c;
+ }
+}
+
+// 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; }
+
+ // C::f itself.
+ // CHECK: define {{.*}} @_ZN6Test111C1fEv(
+
+ // 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(
+
+ // 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(
+}
+
+// Varargs thunk test.
+namespace Test12 {
+ struct A {
+ virtual A* f(int x, ...);
+ };
+ struct B {
+ virtual B* f(int x, ...);
+ };
+ struct C : A, B {
+ virtual void c();
+ virtual C* f(int x, ...);
+ };
+ C* C::f(int x, ...) { return this; }
+
+ // C::f
+ // CHECK: define {{.*}} @_ZN6Test121C1fEiz
+
+ // Varargs thunk; check that both the this and covariant adjustments
+ // are generated.
+ // CHECK: define {{.*}} @_ZTchn8_h8_N6Test121C1fEiz
+ // CHECK: getelementptr inbounds i8, i8* {{.*}}, i64 -8
+ // CHECK: getelementptr inbounds i8, i8* {{.*}}, i64 8
+}
+
+// PR13832
+namespace Test13 {
+ struct B1 {
+ virtual B1 &foo1();
+ };
+ struct Pad1 {
+ virtual ~Pad1();
+ };
+ struct Proxy1 : Pad1, B1 {
+ virtual ~Proxy1();
+ };
+ struct D : virtual Proxy1 {
+ virtual ~D();
+ virtual D &foo1();
+ };
+ D& D::foo1() {
+ return *this;
+ }
+ // CHECK: define {{.*}} @_ZTcvn8_n32_v8_n24_N6Test131D4foo1Ev
+ // CHECK: getelementptr inbounds i8, i8* {{.*}}, i64 -8
+ // CHECK: getelementptr inbounds i8, i8* {{.*}}, i64 -32
+ // CHECK: getelementptr inbounds i8, i8* {{.*}}, i64 -24
+ // CHECK: getelementptr inbounds i8, i8* {{.*}}, i64 8
+ // CHECK: ret %"struct.Test13::D"*
+}
+
+namespace Test14 {
+ class A {
+ virtual void f();
+ };
+ class B {
+ virtual void f();
+ };
+ class C : public A, public B {
+ virtual void f();
+ };
+ void C::f() {
+ }
+ // CHECK: define void @_ZThn8_N6Test141C1fEv({{.*}}) unnamed_addr [[NUW:#[0-9]+]]
+}
+
+// Varargs non-covariant thunk test.
+// PR18098
+namespace Test15 {
+ struct A {
+ virtual ~A();
+ };
+ struct B {
+ virtual void f(int x, ...);
+ };
+ struct C : A, B {
+ virtual void c();
+ virtual void f(int x, ...);
+ };
+ void C::c() {}
+
+ // C::c
+ // CHECK: declare void @_ZN6Test151C1fEiz
+ // non-virtual thunk to C::f
+ // CHECK: declare void @_ZThn8_N6Test151C1fEiz
+}
+
+namespace Test16 {
+struct A {
+ virtual ~A();
+};
+struct B {
+ virtual void foo();
+};
+struct C : public A, public B {
+ void foo() {}
+};
+struct D : public C {
+ ~D();
+};
+D::~D() {}
+// CHECK: define linkonce_odr void @_ZThn8_N6Test161C3fooEv({{.*}}) {{.*}} comdat
+}
+
+/**** The following has to go at the end of the file ****/
+
+// checking without opt
+// CHECK-NONOPT-LABEL: define internal void @_ZThn8_N6Test4B12_GLOBAL__N_11C1fEv(
+// CHECK-NONOPT-NOT: comdat
+
+// This is from Test5:
+// CHECK-NONOPT-LABEL: define linkonce_odr void @_ZTv0_n24_N5Test51B1fEv
+
+// This is from Test10:
+// CHECK-NONOPT-LABEL: define linkonce_odr void @_ZN6Test101C3fooEv
+// CHECK-NONOPT-LABEL: define linkonce_odr void @_ZThn8_N6Test101C3fooEv
+
+// Checking with opt
+// CHECK-OPT-LABEL: define internal void @_ZThn8_N6Test4B12_GLOBAL__N_11C1fEv(%"struct.Test4B::(anonymous namespace)::C"* %this) unnamed_addr #0 align 2
+
+// This is from Test5:
+// CHECK-OPT-LABEL: define linkonce_odr void @_ZTv0_n24_N5Test51B1fEv
+
+// This is from Test10:
+// CHECK-OPT-LABEL: define linkonce_odr void @_ZN6Test101C3fooEv
+// CHECK-OPT-LABEL: define linkonce_odr void @_ZThn8_N6Test101C3fooEv
+
+// CHECK-NONOPT: attributes [[NUW]] = { noinline nounwind optnone uwtable{{.*}} }
+// CHECK-OPT: attributes [[NUW]] = { nounwind uwtable{{.*}} }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/tls-init-funcs.cpp b/src/llvm-project/clang/test/CodeGenCXX/tls-init-funcs.cpp
new file mode 100644
index 0000000..a2a563b
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/tls-init-funcs.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.8 -std=c++1y -S -emit-llvm %s -o - | FileCheck %s
+
+// CHECK: @a = internal thread_local global
+// CHECK: @_Z2vtIiE = linkonce_odr thread_local global i32 5
+// CHECK: @_ZZ3inlvE3loc = linkonce_odr thread_local global i32 0
+// CHECK: @_tlv_atexit({{.*}}@_ZN1AD1Ev
+// CHECK: call cxx_fast_tlscc i32* @_ZTW3ext()
+// CHECK: declare cxx_fast_tlscc i32* @_ZTW3ext()
+// CHECK: define weak_odr hidden cxx_fast_tlscc i32* @_ZTW2vtIiE()
+// CHECK: define weak_odr hidden cxx_fast_tlscc i32* @_ZTW2vtIvE()
+// CHECK: define {{.*}} @_ZTW1a
+
+struct A {
+ ~A();
+};
+
+thread_local A a;
+
+extern thread_local int ext;
+int &get_ext() { return ext; }
+
+template <typename T>
+thread_local int vt = 5;
+
+int get_vt() { return vt<int>; }
+
+inline int &inl() {
+ thread_local int loc;
+ return loc;
+}
+int &use_inl() { return inl(); }
+
+template int vt<void>;
+int &get_vt_void() { return vt<void>; }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/tmp-md-nodes1.cpp b/src/llvm-project/clang/test/CodeGenCXX/tmp-md-nodes1.cpp
new file mode 100644
index 0000000..41a0159
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/tmp-md-nodes1.cpp
@@ -0,0 +1,18 @@
+// REQUIRES: asserts
+// RUN: %clang_cc1 -O0 -triple %itanium_abi_triple -debug-info-kind=limited -S -emit-llvm %s -o - | \
+// RUN: FileCheck %s
+
+// This test simply checks that the varargs thunk is created. The failing test
+// case asserts.
+
+struct Alpha {
+ virtual void bravo(...);
+};
+struct Charlie {
+ virtual ~Charlie() {}
+};
+struct CharlieImpl : Charlie, Alpha {
+ void bravo(...) {}
+} delta;
+
+// CHECK: define {{.*}} void @_ZThn{{[48]}}_N11CharlieImpl5bravoEz(
diff --git a/src/llvm-project/clang/test/CodeGenCXX/tmp-md-nodes2.cpp b/src/llvm-project/clang/test/CodeGenCXX/tmp-md-nodes2.cpp
new file mode 100644
index 0000000..e50220c
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/tmp-md-nodes2.cpp
@@ -0,0 +1,33 @@
+// REQUIRES: asserts
+// RUN: %clang_cc1 -O0 -triple %itanium_abi_triple -debug-info-kind=limited -S -emit-llvm %s -o - | \
+// RUN: FileCheck %s
+
+// This test simply checks that the varargs thunk is created. The failing test
+// case asserts.
+
+typedef signed char __int8_t;
+typedef int BOOL;
+class CMsgAgent;
+
+class CFs {
+public:
+ typedef enum {} CACHE_HINT;
+ virtual BOOL ReqCacheHint( CMsgAgent* p_ma, CACHE_HINT hint, ... ) ;
+};
+
+typedef struct {} _Lldiv_t;
+
+class CBdVfs {
+public:
+ virtual ~CBdVfs( ) {}
+};
+
+class CBdVfsImpl : public CBdVfs, public CFs {
+ BOOL ReqCacheHint( CMsgAgent* p_ma, CACHE_HINT hint, ... );
+};
+
+BOOL CBdVfsImpl::ReqCacheHint( CMsgAgent* p_ma, CACHE_HINT hint, ... ) {
+ return true;
+}
+
+// CHECK: define {{.*}} @_ZThn{{[48]}}_N10CBdVfsImpl12ReqCacheHintEP9CMsgAgentN3CFs10CACHE_HINTEz(
diff --git a/src/llvm-project/clang/test/CodeGenCXX/trap-fnattr.cpp b/src/llvm-project/clang/test/CodeGenCXX/trap-fnattr.cpp
new file mode 100644
index 0000000..166bbad
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/trap-fnattr.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -O0 -emit-llvm -ftrapv -ftrap-function=mytrap %s -o - | FileCheck %s -check-prefix=TRAPFUNC
+// RUN: %clang_cc1 -O0 -emit-llvm -ftrapv %s -o - | FileCheck %s -check-prefix=NOOPTION
+
+// TRAPFUNC-LABEL: define {{(dso_local )?}}void @{{_Z12test_builtinv|\"\?test_builtin@@YAXXZ\"}}
+// TRAPFUNC: call void @llvm.trap() [[ATTR0:#[0-9]+]]
+
+// NOOPTION-LABEL: define {{(dso_local )?}}void @{{_Z12test_builtinv|\"\?test_builtin@@YAXXZ\"}}
+// NOOPTION: call void @llvm.trap(){{$}}
+
+void test_builtin(void) {
+ __builtin_trap();
+}
+
+// TRAPFUNC-LABEL: define {{.*}}i32 @{{_Z13test_noreturnv|\"\?test_noreturn@@YAHXZ\"}}
+// TRAPFUNC: call void @llvm.trap() [[ATTR0]]
+
+// NOOPTION-LABEL: define {{.*}}i32 @{{_Z13test_noreturnv|\"\?test_noreturn@@YAHXZ\"}}
+// NOOPTION: call void @llvm.trap(){{$}}
+
+int test_noreturn(void) {
+}
+
+// TRAPFUNC-LABEL: define {{.*}}i32 @{{_Z17test_add_overflowii|\"\?test_add_overflow@@YAHHH@Z\"}}
+// TRAPFUNC: call void @llvm.trap() [[ATTR1:#[0-9]+]]
+
+// NOOPTION-LABEL: define {{.*}}i32 @{{_Z17test_add_overflowii|\"\?test_add_overflow@@YAHHH@Z\"}}
+// NOOPTION: call void @llvm.trap() [[ATTR2:#[0-9]+]]
+
+int test_add_overflow(int a, int b) {
+ return a + b;
+}
+
+// TRAPFUNC: attributes [[ATTR0]] = { {{.*}}"trap-func-name"="mytrap" }
+// TRAPFUNC: attributes [[ATTR1]] = { {{.*}}"trap-func-name"="mytrap" }
+
+// NOOPTION-NOT: attributes [[ATTR2]] = { {{.*}}"trap-func-name"="mytrap" }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/trivial-auto-var-init-attribute.cpp b/src/llvm-project/clang/test/CodeGenCXX/trivial-auto-var-init-attribute.cpp
new file mode 100644
index 0000000..e7c9e9a
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/trivial-auto-var-init-attribute.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fblocks %s -emit-llvm -o - | FileCheck %s -check-prefix=UNINIT
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fblocks -ftrivial-auto-var-init=pattern %s -emit-llvm -o - | FileCheck %s -check-prefix=PATTERN
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fblocks -ftrivial-auto-var-init=zero %s -emit-llvm -o - | FileCheck %s -check-prefix=ZERO
+
+template<typename T> void used(T &) noexcept;
+
+extern "C" {
+
+// UNINIT-LABEL: test_attribute_uninitialized(
+// UNINIT: alloca
+// UNINIT-NEXT: call void
+// ZERO-LABEL: test_attribute_uninitialized(
+// ZERO: alloca
+// ZERO-NEXT: call void
+// PATTERN-LABEL: test_attribute_uninitialized(
+// PATTERN: alloca
+// PATTERN-NEXT: call void
+void test_attribute_uninitialized() {
+ [[clang::uninitialized]] int i;
+ used(i);
+}
+
+} // extern "C"
diff --git a/src/llvm-project/clang/test/CodeGenCXX/trivial-auto-var-init.cpp b/src/llvm-project/clang/test/CodeGenCXX/trivial-auto-var-init.cpp
new file mode 100644
index 0000000..0a9ad86
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/trivial-auto-var-init.cpp
@@ -0,0 +1,263 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fblocks %s -emit-llvm -o - | FileCheck %s -check-prefix=UNINIT
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fblocks -ftrivial-auto-var-init=pattern %s -emit-llvm -o - | FileCheck %s -check-prefix=PATTERN
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fblocks -ftrivial-auto-var-init=zero %s -emit-llvm -o - | FileCheck %s -check-prefix=ZERO
+
+// None of the synthesized globals should contain `undef`.
+// PATTERN-NOT: undef
+// ZERO-NOT: undef
+
+template<typename T> void used(T &) noexcept;
+
+extern "C" {
+
+// UNINIT-LABEL: test_selfinit(
+// ZERO-LABEL: test_selfinit(
+// ZERO: store i32 0, i32* %self, align 4
+// PATTERN-LABEL: test_selfinit(
+// PATTERN: store i32 -1431655766, i32* %self, align 4
+void test_selfinit() {
+ int self = self + 1;
+ used(self);
+}
+
+// UNINIT-LABEL: test_block(
+// ZERO-LABEL: test_block(
+// ZERO: store i32 0, i32* %block
+// PATTERN-LABEL: test_block(
+// PATTERN: store i32 -1431655766, i32* %block
+void test_block() {
+ __block int block;
+ used(block);
+}
+
+// Using the variable being initialized is typically UB in C, but for blocks we
+// can be nice: they imply extra book-keeping and we can do the auto-init before
+// any of said book-keeping.
+//
+// UNINIT-LABEL: test_block_self_init(
+// ZERO-LABEL: test_block_self_init(
+// ZERO: %block = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i8* }>, align 8
+// ZERO: %captured1 = getelementptr inbounds %struct.__block_byref_captured, %struct.__block_byref_captured* %captured, i32 0, i32 4
+// ZERO-NEXT: store %struct.XYZ* null, %struct.XYZ** %captured1, align 8
+// ZERO: %call = call %struct.XYZ* @create(
+// PATTERN-LABEL: test_block_self_init(
+// PATTERN: %block = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i8* }>, align 8
+// PATTERN: %captured1 = getelementptr inbounds %struct.__block_byref_captured, %struct.__block_byref_captured* %captured, i32 0, i32 4
+// PATTERN-NEXT: store %struct.XYZ* inttoptr (i64 -6148914691236517206 to %struct.XYZ*), %struct.XYZ** %captured1, align 8
+// PATTERN: %call = call %struct.XYZ* @create(
+using Block = void (^)();
+typedef struct XYZ {
+ Block block;
+} * xyz_t;
+void test_block_self_init() {
+ extern xyz_t create(Block block);
+ __block xyz_t captured = create(^() {
+ used(captured);
+ });
+}
+
+// Capturing with escape after initialization is also an edge case.
+//
+// UNINIT-LABEL: test_block_captures_self_after_init(
+// ZERO-LABEL: test_block_captures_self_after_init(
+// ZERO: %block = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i8* }>, align 8
+// ZERO: %captured1 = getelementptr inbounds %struct.__block_byref_captured.1, %struct.__block_byref_captured.1* %captured, i32 0, i32 4
+// ZERO-NEXT: store %struct.XYZ* null, %struct.XYZ** %captured1, align 8
+// ZERO: %call = call %struct.XYZ* @create(
+// PATTERN-LABEL: test_block_captures_self_after_init(
+// PATTERN: %block = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i8* }>, align 8
+// PATTERN: %captured1 = getelementptr inbounds %struct.__block_byref_captured.1, %struct.__block_byref_captured.1* %captured, i32 0, i32 4
+// PATTERN-NEXT: store %struct.XYZ* inttoptr (i64 -6148914691236517206 to %struct.XYZ*), %struct.XYZ** %captured1, align 8
+// PATTERN: %call = call %struct.XYZ* @create(
+void test_block_captures_self_after_init() {
+ extern xyz_t create(Block block);
+ __block xyz_t captured;
+ captured = create(^() {
+ used(captured);
+ });
+}
+
+// This type of code is currently not handled by zero / pattern initialization.
+// The test will break when that is fixed.
+// UNINIT-LABEL: test_goto_unreachable_value(
+// ZERO-LABEL: test_goto_unreachable_value(
+// ZERO-NOT: store {{.*}}%oops
+// PATTERN-LABEL: test_goto_unreachable_value(
+// PATTERN-NOT: store {{.*}}%oops
+void test_goto_unreachable_value() {
+ goto jump;
+ int oops;
+ jump:
+ used(oops);
+}
+
+// This type of code is currently not handled by zero / pattern initialization.
+// The test will break when that is fixed.
+// UNINIT-LABEL: test_goto(
+// ZERO-LABEL: test_goto(
+// ZERO: if.then:
+// ZERO: br label %jump
+// ZERO: store i32 0, i32* %oops, align 4
+// ZERO: br label %jump
+// ZERO: jump:
+// PATTERN-LABEL: test_goto(
+// PATTERN: if.then:
+// PATTERN: br label %jump
+// PATTERN: store i32 -1431655766, i32* %oops, align 4
+// PATTERN: br label %jump
+// PATTERN: jump:
+void test_goto(int i) {
+ if (i)
+ goto jump;
+ int oops;
+ jump:
+ used(oops);
+}
+
+// This type of code is currently not handled by zero / pattern initialization.
+// The test will break when that is fixed.
+// UNINIT-LABEL: test_switch(
+// ZERO-LABEL: test_switch(
+// ZERO: sw.bb:
+// ZERO-NEXT: store i32 0, i32* %oops, align 4
+// ZERO: sw.bb1:
+// ZERO-NEXT: call void @{{.*}}used
+// PATTERN-LABEL: test_switch(
+// PATTERN: sw.bb:
+// PATTERN-NEXT: store i32 -1431655766, i32* %oops, align 4
+// PATTERN: sw.bb1:
+// PATTERN-NEXT: call void @{{.*}}used
+void test_switch(int i) {
+ switch (i) {
+ case 0:
+ int oops;
+ break;
+ case 1:
+ used(oops);
+ }
+}
+
+// UNINIT-LABEL: test_vla(
+// ZERO-LABEL: test_vla(
+// ZERO: %[[SIZE:[0-9]+]] = mul nuw i64 %{{.*}}, 4
+// ZERO: call void @llvm.memset{{.*}}(i8* align 16 %{{.*}}, i8 0, i64 %[[SIZE]], i1 false)
+// PATTERN-LABEL: test_vla(
+// PATTERN: %vla.iszerosized = icmp eq i64 %{{.*}}, 0
+// PATTERN: br i1 %vla.iszerosized, label %vla-init.cont, label %vla-setup.loop
+// PATTERN: vla-setup.loop:
+// PATTERN: %[[SIZE:[0-9]+]] = mul nuw i64 %{{.*}}, 4
+// PATTERN: %vla.begin = bitcast i32* %vla to i8*
+// PATTERN: %vla.end = getelementptr inbounds i8, i8* %vla.begin, i64 %[[SIZE]]
+// PATTERN: br label %vla-init.loop
+// PATTERN: vla-init.loop:
+// PATTERN: %vla.cur = phi i8* [ %vla.begin, %vla-setup.loop ], [ %vla.next, %vla-init.loop ]
+// PATTERN: call void @llvm.memcpy{{.*}} %vla.cur, {{.*}}@__const.test_vla.vla
+// PATTERN: %vla.next = getelementptr inbounds i8, i8* %vla.cur, i64 4
+// PATTERN: %vla-init.isdone = icmp eq i8* %vla.next, %vla.end
+// PATTERN: br i1 %vla-init.isdone, label %vla-init.cont, label %vla-init.loop
+// PATTERN: vla-init.cont:
+// PATTERN: call void @{{.*}}used
+void test_vla(int size) {
+ // Variable-length arrays can't have a zero size according to C11 6.7.6.2/5.
+ // Neither can they be negative-sized.
+ //
+ // We don't use the former fact because some code creates zero-sized VLAs and
+ // doesn't use them. clang makes these share locations with other stack
+ // values, which leads to initialization of the wrong values.
+ //
+ // We rely on the later fact because it generates better code.
+ //
+ // Both cases are caught by UBSan.
+ int vla[size];
+ int *ptr = vla;
+ used(ptr);
+}
+
+// UNINIT-LABEL: test_struct_vla(
+// ZERO-LABEL: test_struct_vla(
+// ZERO: %[[SIZE:[0-9]+]] = mul nuw i64 %{{.*}}, 16
+// ZERO: call void @llvm.memset{{.*}}(i8* align 16 %{{.*}}, i8 0, i64 %[[SIZE]], i1 false)
+// PATTERN-LABEL: test_struct_vla(
+// PATTERN: %vla.iszerosized = icmp eq i64 %{{.*}}, 0
+// PATTERN: br i1 %vla.iszerosized, label %vla-init.cont, label %vla-setup.loop
+// PATTERN: vla-setup.loop:
+// PATTERN: %[[SIZE:[0-9]+]] = mul nuw i64 %{{.*}}, 16
+// PATTERN: %vla.begin = bitcast %struct.anon* %vla to i8*
+// PATTERN: %vla.end = getelementptr inbounds i8, i8* %vla.begin, i64 %[[SIZE]]
+// PATTERN: br label %vla-init.loop
+// PATTERN: vla-init.loop:
+// PATTERN: %vla.cur = phi i8* [ %vla.begin, %vla-setup.loop ], [ %vla.next, %vla-init.loop ]
+// PATTERN: call void @llvm.memcpy{{.*}} %vla.cur, {{.*}}@__const.test_struct_vla.vla
+// PATTERN: %vla.next = getelementptr inbounds i8, i8* %vla.cur, i64 16
+// PATTERN: %vla-init.isdone = icmp eq i8* %vla.next, %vla.end
+// PATTERN: br i1 %vla-init.isdone, label %vla-init.cont, label %vla-init.loop
+// PATTERN: vla-init.cont:
+// PATTERN: call void @{{.*}}used
+void test_struct_vla(int size) {
+ // Same as above, but with a struct that doesn't just memcpy.
+ struct {
+ float f;
+ char c;
+ void *ptr;
+ } vla[size];
+ void *ptr = static_cast<void*>(vla);
+ used(ptr);
+}
+
+// UNINIT-LABEL: test_zsa(
+// ZERO-LABEL: test_zsa(
+// ZERO: %zsa = alloca [0 x i32], align 4
+// ZERO-NOT: %zsa
+// ZERO: call void @{{.*}}used
+// PATTERN-LABEL: test_zsa(
+// PATTERN: %zsa = alloca [0 x i32], align 4
+// PATTERN-NOT: %zsa
+// PATTERN: call void @{{.*}}used
+void test_zsa(int size) {
+ // Technically not valid, but as long as clang accepts them we should do
+ // something sensible (i.e. not store to the zero-size array).
+ int zsa[0];
+ used(zsa);
+}
+
+// UNINIT-LABEL: test_huge_uninit(
+// ZERO-LABEL: test_huge_uninit(
+// ZERO: call void @llvm.memset{{.*}}, i8 0, i64 65536,
+// PATTERN-LABEL: test_huge_uninit(
+// PATTERN: call void @llvm.memset{{.*}}, i8 -86, i64 65536,
+void test_huge_uninit() {
+ // We can't emit this as an inline constant to a store instruction because
+ // SDNode hits an internal size limit.
+ char big[65536];
+ used(big);
+}
+
+// UNINIT-LABEL: test_huge_small_init(
+// ZERO-LABEL: test_huge_small_init(
+// ZERO: call void @llvm.memset{{.*}}, i8 0, i64 65536,
+// ZERO: store i8 97,
+// ZERO: store i8 98,
+// ZERO: store i8 99,
+// ZERO: store i8 100,
+// PATTERN-LABEL: test_huge_small_init(
+// PATTERN: call void @llvm.memset{{.*}}, i8 0, i64 65536,
+// PATTERN: store i8 97,
+// PATTERN: store i8 98,
+// PATTERN: store i8 99,
+// PATTERN: store i8 100,
+void test_huge_small_init() {
+ char big[65536] = { 'a', 'b', 'c', 'd' };
+ used(big);
+}
+
+// UNINIT-LABEL: test_huge_larger_init(
+// ZERO-LABEL: test_huge_larger_init(
+// ZERO: call void @llvm.memcpy{{.*}} @__const.test_huge_larger_init.big, {{.*}}, i64 65536,
+// PATTERN-LABEL: test_huge_larger_init(
+// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_huge_larger_init.big, {{.*}}, i64 65536,
+void test_huge_larger_init() {
+ char big[65536] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
+ used(big);
+}
+
+} // extern "C"
diff --git a/src/llvm-project/clang/test/CodeGenCXX/trivial-constructor-init.cpp b/src/llvm-project/clang/test/CodeGenCXX/trivial-constructor-init.cpp
new file mode 100644
index 0000000..da17799
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/trivial-constructor-init.cpp
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -std=c++11 -triple %itanium_abi_triple | FileCheck %s
+
+extern "C" int printf(...);
+
+struct S {
+ S() { printf("S::S\n"); }
+};
+
+struct A {
+ double x;
+ A() : x(), y(), s() { printf("x = %f y = %x \n", x, y); }
+ int *y;
+ S s;
+};
+
+A a;
+
+struct B {
+ B() = default;
+ B(const B&);
+};
+
+// CHECK-NOT: _ZL1b
+static B b;
+
+struct C {
+ ~C();
+};
+
+// CHECK: _ZL1c
+static C c[4];
+
+int main() {
+}
+
+namespace PR22793 {
+template <typename>
+struct foo {
+protected:
+// CHECK-NOT: _ZN7PR227933fooIiED2Ev
+ ~foo() = default;
+ friend void func();
+};
+
+void func() { foo<int> f; }
+
+template struct foo<int>;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/trivial_abi.cpp b/src/llvm-project/clang/test/CodeGenCXX/trivial_abi.cpp
new file mode 100644
index 0000000..2cf07b2
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/trivial_abi.cpp
@@ -0,0 +1,239 @@
+// RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++11 -fcxx-exceptions -fexceptions -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++11 -fcxx-exceptions -fexceptions -fclang-abi-compat=4.0 -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: %[[STRUCT_SMALL:.*]] = type { i32* }
+// CHECK: %[[STRUCT_LARGE:.*]] = type { i32*, [128 x i32] }
+// CHECK: %[[STRUCT_TRIVIAL:.*]] = type { i32 }
+// CHECK: %[[STRUCT_NONTRIVIAL:.*]] = type { i32 }
+
+struct __attribute__((trivial_abi)) Small {
+ int *p;
+ Small();
+ ~Small();
+ Small(const Small &) noexcept;
+ Small &operator=(const Small &);
+};
+
+struct __attribute__((trivial_abi)) Large {
+ int *p;
+ int a[128];
+ Large();
+ ~Large();
+ Large(const Large &) noexcept;
+ Large &operator=(const Large &);
+};
+
+struct Trivial {
+ int a;
+};
+
+struct NonTrivial {
+ NonTrivial();
+ ~NonTrivial();
+ int a;
+};
+
+struct HasTrivial {
+ Small s;
+ Trivial m;
+};
+
+struct HasNonTrivial {
+ Small s;
+ NonTrivial m;
+};
+
+// CHECK: define void @_Z14testParamSmall5Small(i64 %[[A_COERCE:.*]])
+// CHECK: %[[A:.*]] = alloca %[[STRUCT_SMALL]], align 8
+// CHECK: %[[COERCE_DIVE:.*]] = getelementptr inbounds %[[STRUCT_SMALL]], %[[STRUCT_SMALL]]* %[[A]], i32 0, i32 0
+// CHECK: %[[COERCE_VAL_IP:.*]] = inttoptr i64 %[[A_COERCE]] to i32*
+// CHECK: store i32* %[[COERCE_VAL_IP]], i32** %[[COERCE_DIVE]], align 8
+// CHECK: %[[CALL:.*]] = call %[[STRUCT_SMALL]]* @_ZN5SmallD1Ev(%[[STRUCT_SMALL]]* %[[A]])
+// CHECK: ret void
+// CHECK: }
+
+void testParamSmall(Small a) noexcept {
+}
+
+// CHECK: define i64 @_Z15testReturnSmallv()
+// CHECK: %[[RETVAL:.*]] = alloca %[[STRUCT_SMALL:.*]], align 8
+// CHECK: %[[CALL:.*]] = call %[[STRUCT_SMALL]]* @_ZN5SmallC1Ev(%[[STRUCT_SMALL]]* %[[RETVAL]])
+// CHECK: %[[COERCE_DIVE:.*]] = getelementptr inbounds %[[STRUCT_SMALL]], %[[STRUCT_SMALL]]* %[[RETVAL]], i32 0, i32 0
+// CHECK: %[[V0:.*]] = load i32*, i32** %[[COERCE_DIVE]], align 8
+// CHECK: %[[COERCE_VAL_PI:.*]] = ptrtoint i32* %[[V0]] to i64
+// CHECK: ret i64 %[[COERCE_VAL_PI]]
+// CHECK: }
+
+Small testReturnSmall() {
+ Small t;
+ return t;
+}
+
+// CHECK: define void @_Z14testCallSmall0v()
+// CHECK: %[[T:.*]] = alloca %[[STRUCT_SMALL:.*]], align 8
+// CHECK: %[[AGG_TMP:.*]] = alloca %[[STRUCT_SMALL]], align 8
+// CHECK: %[[CALL:.*]] = call %[[STRUCT_SMALL]]* @_ZN5SmallC1Ev(%[[STRUCT_SMALL]]* %[[T]])
+// CHECK: %[[CALL1:.*]] = call %[[STRUCT_SMALL]]* @_ZN5SmallC1ERKS_(%[[STRUCT_SMALL]]* %[[AGG_TMP]], %[[STRUCT_SMALL]]* dereferenceable(8) %[[T]])
+// CHECK: %[[COERCE_DIVE:.*]] = getelementptr inbounds %[[STRUCT_SMALL]], %[[STRUCT_SMALL]]* %[[AGG_TMP]], i32 0, i32 0
+// CHECK: %[[V0:.*]] = load i32*, i32** %[[COERCE_DIVE]], align 8
+// CHECK: %[[COERCE_VAL_PI:.*]] = ptrtoint i32* %[[V0]] to i64
+// CHECK: call void @_Z14testParamSmall5Small(i64 %[[COERCE_VAL_PI]])
+// CHECK: %[[CALL2:.*]] = call %[[STRUCT_SMALL]]* @_ZN5SmallD1Ev(%[[STRUCT_SMALL]]* %[[T]])
+// CHECK: ret void
+// CHECK: }
+
+void testCallSmall0() {
+ Small t;
+ testParamSmall(t);
+}
+
+// CHECK: define void @_Z14testCallSmall1v()
+// CHECK: %[[AGG_TMP:.*]] = alloca %[[STRUCT_SMALL:.*]], align 8
+// CHECK: %[[CALL:.*]] = call i64 @_Z15testReturnSmallv()
+// CHECK: %[[COERCE_DIVE:.*]] = getelementptr inbounds %[[STRUCT_SMALL]], %[[STRUCT_SMALL]]* %[[AGG_TMP]], i32 0, i32 0
+// CHECK: %[[COERCE_VAL_IP:.*]] = inttoptr i64 %[[CALL]] to i32*
+// CHECK: store i32* %[[COERCE_VAL_IP]], i32** %[[COERCE_DIVE]], align 8
+// CHECK: %[[COERCE_DIVE1:.*]] = getelementptr inbounds %[[STRUCT_SMALL]], %[[STRUCT_SMALL]]* %[[AGG_TMP]], i32 0, i32 0
+// CHECK: %[[V0:.*]] = load i32*, i32** %[[COERCE_DIVE1]], align 8
+// CHECK: %[[COERCE_VAL_PI:.*]] = ptrtoint i32* %[[V0]] to i64
+// CHECK: call void @_Z14testParamSmall5Small(i64 %[[COERCE_VAL_PI]])
+// CHECK: ret void
+// CHECK: }
+
+void testCallSmall1() {
+ testParamSmall(testReturnSmall());
+}
+
+// CHECK: define void @_Z16testIgnoredSmallv()
+// CHECK: %[[AGG_TMP_ENSURED:.*]] = alloca %[[STRUCT_SMALL:.*]], align 8
+// CHECK: %[[CALL:.*]] = call i64 @_Z15testReturnSmallv()
+// CHECK: %[[COERCE_DIVE:.*]] = getelementptr inbounds %[[STRUCT_SMALL]], %[[STRUCT_SMALL]]* %[[AGG_TMP_ENSURED]], i32 0, i32 0
+// CHECK: %[[COERCE_VAL_IP:.*]] = inttoptr i64 %[[CALL]] to i32*
+// CHECK: store i32* %[[COERCE_VAL_IP]], i32** %[[COERCE_DIVE]], align 8
+// CHECK: %[[CALL1:.*]] = call %[[STRUCT_SMALL]]* @_ZN5SmallD1Ev(%[[STRUCT_SMALL]]* %[[AGG_TMP_ENSURED]])
+// CHECK: ret void
+// CHECK: }
+
+void testIgnoredSmall() {
+ testReturnSmall();
+}
+
+// CHECK: define void @_Z14testParamLarge5Large(%[[STRUCT_LARGE:.*]]* %[[A:.*]])
+// CHECK: %[[CALL:.*]] = call %[[STRUCT_LARGE]]* @_ZN5LargeD1Ev(%[[STRUCT_LARGE]]* %[[A]])
+// CHECK: ret void
+// CHECK: }
+
+void testParamLarge(Large a) noexcept {
+}
+
+// CHECK: define void @_Z15testReturnLargev(%[[STRUCT_LARGE:.*]]* noalias sret %[[AGG_RESULT:.*]])
+// CHECK: %[[CALL:.*]] = call %[[STRUCT_LARGE]]* @_ZN5LargeC1Ev(%[[STRUCT_LARGE]]* %[[AGG_RESULT]])
+// CHECK: ret void
+// CHECK: }
+
+Large testReturnLarge() {
+ Large t;
+ return t;
+}
+
+// CHECK: define void @_Z14testCallLarge0v()
+// CHECK: %[[T:.*]] = alloca %[[STRUCT_LARGE:.*]], align 8
+// CHECK: %[[AGG_TMP:.*]] = alloca %[[STRUCT_LARGE]], align 8
+// CHECK: %[[CALL:.*]] = call %[[STRUCT_LARGE]]* @_ZN5LargeC1Ev(%[[STRUCT_LARGE]]* %[[T]])
+// CHECK: %[[CALL1:.*]] = call %[[STRUCT_LARGE]]* @_ZN5LargeC1ERKS_(%[[STRUCT_LARGE]]* %[[AGG_TMP]], %[[STRUCT_LARGE]]* dereferenceable(520) %[[T]])
+// CHECK: call void @_Z14testParamLarge5Large(%[[STRUCT_LARGE]]* %[[AGG_TMP]])
+// CHECK: %[[CALL2:.*]] = call %[[STRUCT_LARGE]]* @_ZN5LargeD1Ev(%[[STRUCT_LARGE]]* %[[T]])
+// CHECK: ret void
+// CHECK: }
+
+void testCallLarge0() {
+ Large t;
+ testParamLarge(t);
+}
+
+// CHECK: define void @_Z14testCallLarge1v()
+// CHECK: %[[AGG_TMP:.*]] = alloca %[[STRUCT_LARGE:.*]], align 8
+// CHECK: call void @_Z15testReturnLargev(%[[STRUCT_LARGE]]* sret %[[AGG_TMP]])
+// CHECK: call void @_Z14testParamLarge5Large(%[[STRUCT_LARGE]]* %[[AGG_TMP]])
+// CHECK: ret void
+// CHECK: }
+
+void testCallLarge1() {
+ testParamLarge(testReturnLarge());
+}
+
+// CHECK: define void @_Z16testIgnoredLargev()
+// CHECK: %[[AGG_TMP_ENSURED:.*]] = alloca %[[STRUCT_LARGE:.*]], align 8
+// CHECK: call void @_Z15testReturnLargev(%[[STRUCT_LARGE]]* sret %[[AGG_TMP_ENSURED]])
+// CHECK: %[[CALL:.*]] = call %[[STRUCT_LARGE]]* @_ZN5LargeD1Ev(%[[STRUCT_LARGE]]* %[[AGG_TMP_ENSURED]])
+// CHECK: ret void
+// CHECK: }
+
+void testIgnoredLarge() {
+ testReturnLarge();
+}
+
+// CHECK: define i64 @_Z20testReturnHasTrivialv()
+// CHECK: %[[RETVAL:.*]] = alloca %[[STRUCT_TRIVIAL:.*]], align 4
+// CHECK: %[[COERCE_DIVE:.*]] = getelementptr inbounds %[[STRUCT_TRIVIAL]], %[[STRUCT_TRIVIAL]]* %[[RETVAL]], i32 0, i32 0
+// CHECK: %[[V0:.*]] = load i32, i32* %[[COERCE_DIVE]], align 4
+// CHECK: %[[COERCE_VAL_II:.*]] = zext i32 %[[V0]] to i64
+// CHECK: ret i64 %[[COERCE_VAL_II]]
+// CHECK: }
+
+Trivial testReturnHasTrivial() {
+ Trivial t;
+ return t;
+}
+
+// CHECK: define void @_Z23testReturnHasNonTrivialv(%[[STRUCT_NONTRIVIAL:.*]]* noalias sret %[[AGG_RESULT:.*]])
+// CHECK: %[[CALL:.*]] = call %[[STRUCT_NONTRIVIAL]]* @_ZN10NonTrivialC1Ev(%[[STRUCT_NONTRIVIAL]]* %[[AGG_RESULT]])
+// CHECK: ret void
+// CHECK: }
+
+NonTrivial testReturnHasNonTrivial() {
+ NonTrivial t;
+ return t;
+}
+
+// CHECK: define void @_Z18testExceptionSmallv()
+// CHECK: %[[AGG_TMP:.*]] = alloca %[[STRUCT_SMALL]], align 8
+// CHECK: %[[AGG_TMP1:.*]] = alloca %[[STRUCT_SMALL]], align 8
+// CHECK: call %[[STRUCT_SMALL]]* @_ZN5SmallC1Ev(%[[STRUCT_SMALL]]* %[[AGG_TMP]])
+// CHECK: invoke %[[STRUCT_SMALL]]* @_ZN5SmallC1Ev(%[[STRUCT_SMALL]]* %[[AGG_TMP1]])
+
+// CHECK: call void @_Z20calleeExceptionSmall5SmallS_(i64 %{{.*}}, i64 %{{.*}})
+// CHECK-NEXT: ret void
+
+// CHECK: landingpad { i8*, i32 }
+// CHECK: call %[[STRUCT_SMALL]]* @_ZN5SmallD1Ev(%[[STRUCT_SMALL]]* %[[AGG_TMP]])
+// CHECK: br
+
+// CHECK: resume { i8*, i32 }
+
+void calleeExceptionSmall(Small, Small);
+
+void testExceptionSmall() {
+ calleeExceptionSmall(Small(), Small());
+}
+
+// CHECK: define void @_Z18testExceptionLargev()
+// CHECK: %[[AGG_TMP:.*]] = alloca %[[STRUCT_LARGE]], align 8
+// CHECK: %[[AGG_TMP1:.*]] = alloca %[[STRUCT_LARGE]], align 8
+// CHECK: call %[[STRUCT_LARGE]]* @_ZN5LargeC1Ev(%[[STRUCT_LARGE]]* %[[AGG_TMP]])
+// CHECK: invoke %[[STRUCT_LARGE]]* @_ZN5LargeC1Ev(%[[STRUCT_LARGE]]* %[[AGG_TMP1]])
+
+// CHECK: call void @_Z20calleeExceptionLarge5LargeS_(%[[STRUCT_LARGE]]* %[[AGG_TMP]], %[[STRUCT_LARGE]]* %[[AGG_TMP1]])
+// CHECK-NEXT: ret void
+
+// CHECK: landingpad { i8*, i32 }
+// CHECK: call %[[STRUCT_LARGE]]* @_ZN5LargeD1Ev(%[[STRUCT_LARGE]]* %[[AGG_TMP]])
+// CHECK: br
+
+// CHECK: resume { i8*, i32 }
+
+void calleeExceptionLarge(Large, Large);
+
+void testExceptionLarge() {
+ calleeExceptionLarge(Large(), Large());
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/try-catch.cpp b/src/llvm-project/clang/test/CodeGenCXX/try-catch.cpp
new file mode 100644
index 0000000..b50214e
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/try-catch.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - -fcxx-exceptions -fexceptions | FileCheck %s
+
+struct X { };
+
+const X g();
+
+void f() {
+ try {
+ throw g();
+ // CHECK: @_ZTI1X to i8
+ } catch (const X x) {
+ }
+}
+
+void h() {
+ try {
+ throw "ABC";
+ // CHECK: @_ZTIPKc to i8
+ } catch (char const(&)[4]) {
+ }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/type-metadata-memfun.cpp b/src/llvm-project/clang/test/CodeGenCXX/type-metadata-memfun.cpp
new file mode 100644
index 0000000..2ff574e
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/type-metadata-memfun.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -flto -flto-unit -triple x86_64-unknown-linux -fvisibility hidden -emit-llvm -o - %s | FileCheck %s
+
+struct S1 {
+ S1();
+ ~S1();
+ virtual void vf();
+ void f();
+ void fdecl();
+};
+
+struct [[clang::lto_visibility_public]] S2 {
+ void f();
+};
+
+// CHECK-NOT: declare{{.*}}!type
+// CHECK-NOT: define{{.*}}!type
+
+S1::S1() {}
+S1::~S1() {}
+void S1::vf() {}
+// CHECK: define hidden void @_ZN2S11fEv{{.*}} !type [[S2F:![0-9]+]]
+void S1::f() {
+ fdecl();
+}
+
+void S2::f() {}
+
+// CHECK-NOT: declare{{.*}}!type
+// CHECK-NOT: define{{.*}}!type
+
+// CHECK: [[S2F]] = !{i64 0, !"_ZTSM2S1FvvE"}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/type-metadata-thinlto.cpp b/src/llvm-project/clang/test/CodeGenCXX/type-metadata-thinlto.cpp
new file mode 100644
index 0000000..8bf39f1
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/type-metadata-thinlto.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -flto=thin -flto-unit -fsplit-lto-unit -triple x86_64-unknown-linux -fvisibility hidden -emit-llvm-bc -o %t %s
+// RUN: llvm-modextract -o - -n 1 %t | llvm-dis | FileCheck %s
+// RUN: llvm-modextract -b -o - -n 1 %t | llvm-bcanalyzer -dump | FileCheck %s --check-prefix=LTOUNIT
+// LTOUNIT: <FLAGS op0=8/>
+
+// CHECK: @_ZTV1A = linkonce_odr
+class A {
+ virtual void f() {}
+};
+
+A *f() {
+ return new A;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/type-metadata.cpp b/src/llvm-project/clang/test/CodeGenCXX/type-metadata.cpp
new file mode 100644
index 0000000..a7a3467
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/type-metadata.cpp
@@ -0,0 +1,291 @@
+// Tests for the cfi-vcall feature:
+// RUN: %clang_cc1 -flto -flto-unit -triple x86_64-unknown-linux -fvisibility hidden -fsanitize=cfi-vcall -fsanitize-trap=cfi-vcall -emit-llvm -o - %s | FileCheck --check-prefix=CFI --check-prefix=CFI-NVT --check-prefix=ITANIUM --check-prefix=TT-ITANIUM --check-prefix=NDIAG %s
+// RUN: %clang_cc1 -flto -flto-unit -triple x86_64-unknown-linux -fvisibility hidden -fsanitize=cfi-vcall -emit-llvm -o - %s | FileCheck --check-prefix=CFI --check-prefix=CFI-NVT --check-prefix=ITANIUM --check-prefix=TT-ITANIUM --check-prefix=ITANIUM-DIAG --check-prefix=DIAG --check-prefix=DIAG-ABORT %s
+// RUN: %clang_cc1 -flto -flto-unit -triple x86_64-unknown-linux -fvisibility hidden -fsanitize=cfi-vcall -fsanitize-recover=cfi-vcall -emit-llvm -o - %s | FileCheck --check-prefix=CFI --check-prefix=CFI-NVT --check-prefix=ITANIUM --check-prefix=TT-ITANIUM --check-prefix=ITANIUM-DIAG --check-prefix=DIAG --check-prefix=DIAG-RECOVER %s
+// RUN: %clang_cc1 -flto -flto-unit -triple x86_64-pc-windows-msvc -fsanitize=cfi-vcall -fsanitize-trap=cfi-vcall -emit-llvm -o - %s | FileCheck --check-prefix=CFI --check-prefix=CFI-NVT --check-prefix=MS --check-prefix=TT-MS --check-prefix=NDIAG %s
+
+// Tests for the whole-program-vtables feature:
+// RUN: %clang_cc1 -flto -flto-unit -triple x86_64-unknown-linux -fvisibility hidden -fwhole-program-vtables -emit-llvm -o - %s | FileCheck --check-prefix=VTABLE-OPT --check-prefix=ITANIUM --check-prefix=TT-ITANIUM %s
+// RUN: %clang_cc1 -flto -flto-unit -triple x86_64-pc-windows-msvc -fwhole-program-vtables -emit-llvm -o - %s | FileCheck --check-prefix=VTABLE-OPT --check-prefix=MS --check-prefix=TT-MS %s
+
+// Tests for cfi + whole-program-vtables:
+// RUN: %clang_cc1 -flto -flto-unit -triple x86_64-unknown-linux -fvisibility hidden -fsanitize=cfi-vcall -fsanitize-trap=cfi-vcall -fwhole-program-vtables -emit-llvm -o - %s | FileCheck --check-prefix=CFI --check-prefix=CFI-VT --check-prefix=ITANIUM --check-prefix=TC-ITANIUM %s
+// RUN: %clang_cc1 -flto -flto-unit -triple x86_64-pc-windows-msvc -fsanitize=cfi-vcall -fsanitize-trap=cfi-vcall -fwhole-program-vtables -emit-llvm -o - %s | FileCheck --check-prefix=CFI --check-prefix=CFI-VT --check-prefix=MS --check-prefix=TC-MS %s
+
+// ITANIUM: @_ZTV1A = {{[^!]*}}, !type [[A16:![0-9]+]]
+// ITANIUM-DIAG-SAME: !type [[ALL16:![0-9]+]]
+// ITANIUM-SAME: !type [[AF16:![0-9]+]]
+
+// ITANIUM: @_ZTV1B = {{[^!]*}}, !type [[A32:![0-9]+]]
+// ITANIUM-DIAG-SAME: !type [[ALL32:![0-9]+]]
+// ITANIUM-SAME: !type [[AF32:![0-9]+]]
+// ITANIUM-SAME: !type [[AF40:![0-9]+]]
+// ITANIUM-SAME: !type [[AF48:![0-9]+]]
+// ITANIUM-SAME: !type [[B32:![0-9]+]]
+// ITANIUM-DIAG-SAME: !type [[ALL32]]
+// ITANIUM-SAME: !type [[BF32:![0-9]+]]
+// ITANIUM-SAME: !type [[BF40:![0-9]+]]
+// ITANIUM-SAME: !type [[BF48:![0-9]+]]
+
+// ITANIUM: @_ZTV1C = {{[^!]*}}, !type [[A32]]
+// ITANIUM-DIAG-SAME: !type [[ALL32]]
+// ITANIUM-SAME: !type [[AF32]]
+// ITANIUM-SAME: !type [[C32:![0-9]+]]
+// ITANIUM-DIAG-SAME: !type [[ALL32]]
+// ITANIUM-SAME: !type [[CF32:![0-9]+]]
+
+// DIAG: @[[SRC:.*]] = private unnamed_addr constant [{{.*}} x i8] c"{{.*}}type-metadata.cpp\00", align 1
+// DIAG: @[[TYPE:.*]] = private unnamed_addr constant { i16, i16, [4 x i8] } { i16 -1, i16 0, [4 x i8] c"'A'\00" }
+// DIAG: @[[BADTYPESTATIC:.*]] = private unnamed_addr global { i8, { [{{.*}} x i8]*, i32, i32 }, { i16, i16, [4 x i8] }* } { i8 0, { [{{.*}} x i8]*, i32, i32 } { [{{.*}} x i8]* @[[SRC]], i32 123, i32 3 }, { i16, i16, [4 x i8] }* @[[TYPE]] }
+
+// ITANIUM: @_ZTVN12_GLOBAL__N_11DE = {{[^!]*}}, !type [[A32]]
+// ITANIUM-DIAG-SAME: !type [[ALL32]]
+// ITANIUM-SAME: !type [[AF32]]
+// ITANIUM-SAME: !type [[AF40]]
+// ITANIUM-SAME: !type [[AF48]]
+// ITANIUM-SAME: !type [[B32]]
+// ITANIUM-DIAG-SAME: !type [[ALL32]]
+// ITANIUM-SAME: !type [[BF32]]
+// ITANIUM-SAME: !type [[BF40]]
+// ITANIUM-SAME: !type [[BF48]]
+// ITANIUM-SAME: !type [[C88:![0-9]+]]
+// ITANIUM-DIAG-SAME: !type [[ALL88:![0-9]+]]
+// ITANIUM-SAME: !type [[CF32]]
+// ITANIUM-SAME: !type [[CF40:![0-9]+]]
+// ITANIUM-SAME: !type [[CF48:![0-9]+]]
+// ITANIUM-SAME: !type [[D32:![0-9]+]]
+// ITANIUM-DIAG-SAME: !type [[ALL32]]
+// ITANIUM-SAME: !type [[DF32:![0-9]+]]
+// ITANIUM-SAME: !type [[DF40:![0-9]+]]
+// ITANIUM-SAME: !type [[DF48:![0-9]+]]
+
+// ITANIUM: @_ZTCN12_GLOBAL__N_11DE0_1B = {{[^!]*}}, !type [[A32]]
+// ITANIUM-DIAG-SAME: !type [[ALL32]]
+// ITANIUM-SAME: !type [[B32]]
+// ITANIUM-DIAG-SAME: !type [[ALL32]]
+
+// ITANIUM: @_ZTCN12_GLOBAL__N_11DE8_1C = {{[^!]*}}, !type [[A64:![0-9]+]]
+// ITANIUM-DIAG-SAME: !type [[ALL64:![0-9]+]]
+// ITANIUM-SAME: !type [[AF64:![0-9]+]]
+// ITANIUM-SAME: !type [[C32]]
+// ITANIUM-DIAG-SAME: !type [[ALL32]]
+// ITANIUM-SAME: !type [[CF64:![0-9]+]]
+
+// ITANIUM: @_ZTVZ3foovE2FA = {{[^!]*}}, !type [[A16]]
+// ITANIUM-DIAG-SAME: !type [[ALL16]]
+// ITANIUM-SAME: !type [[AF16]]
+// ITANIUM-SAME: !type [[FA16:![0-9]+]]
+// ITANIUM-DIAG-SAME: !type [[ALL16]]
+// ITANIUM-SAME: !type [[FAF16:![0-9]+]]
+
+// MS: comdat($"??_7A@@6B@"), !type [[A8:![0-9]+]]
+// MS: comdat($"??_7B@@6B0@@"), !type [[B8:![0-9]+]]
+// MS: comdat($"??_7B@@6BA@@@"), !type [[A8]]
+// MS: comdat($"??_7C@@6B@"), !type [[A8]]
+// MS: comdat($"??_7D@?A0x{{[^@]*}}@@6BB@@@"), !type [[B8]], !type [[D8:![0-9]+]]
+// MS: comdat($"??_7D@?A0x{{[^@]*}}@@6BA@@@"), !type [[A8]]
+// MS: comdat($"??_7FA@?1??foo@@YAXXZ@6B@"), !type [[A8]], !type [[FA8:![0-9]+]]
+
+struct A {
+ A();
+ virtual void f();
+};
+
+struct B : virtual A {
+ B();
+ virtual void g();
+ virtual void h();
+};
+
+struct C : virtual A {
+ C();
+};
+
+namespace {
+
+struct D : B, C {
+ D();
+ virtual void f();
+ virtual void h();
+};
+
+}
+
+A::A() {}
+B::B() {}
+C::C() {}
+D::D() {}
+
+void A::f() {
+}
+
+void B::g() {
+}
+
+void D::f() {
+}
+
+void D::h() {
+}
+
+// ITANIUM: define hidden void @_Z2afP1A
+// MS: define dso_local void @"?af@@YAXPEAUA@@@Z"
+void af(A *a) {
+ // TT-ITANIUM: [[P:%[^ ]*]] = call i1 @llvm.type.test(i8* [[VT:%[^ ]*]], metadata !"_ZTS1A")
+ // TT-MS: [[P:%[^ ]*]] = call i1 @llvm.type.test(i8* [[VT:%[^ ]*]], metadata !"?AUA@@")
+ // TC-ITANIUM: [[PAIR:%[^ ]*]] = call { i8*, i1 } @llvm.type.checked.load(i8* {{%[^ ]*}}, i32 0, metadata !"_ZTS1A")
+ // TC-MS: [[PAIR:%[^ ]*]] = call { i8*, i1 } @llvm.type.checked.load(i8* {{%[^ ]*}}, i32 0, metadata !"?AUA@@")
+ // CFI-VT: [[P:%[^ ]*]] = extractvalue { i8*, i1 } [[PAIR]], 1
+ // DIAG-NEXT: [[VTVALID0:%[^ ]*]] = call i1 @llvm.type.test(i8* [[VT]], metadata !"all-vtables")
+ // VTABLE-OPT: call void @llvm.assume(i1 [[P]])
+ // CFI-NEXT: br i1 [[P]], label %[[CONTBB:[^ ,]*]], label %[[TRAPBB:[^ ,]*]]
+ // CFI-NEXT: {{^$}}
+
+ // CFI: [[TRAPBB]]
+ // NDIAG-NEXT: call void @llvm.trap()
+ // NDIAG-NEXT: unreachable
+ // DIAG-NEXT: [[VTINT:%[^ ]*]] = ptrtoint i8* [[VT]] to i64
+ // DIAG-NEXT: [[VTVALID:%[^ ]*]] = zext i1 [[VTVALID0]] to i64
+ // DIAG-ABORT-NEXT: call void @__ubsan_handle_cfi_check_fail_abort(i8* getelementptr inbounds ({{.*}} @[[BADTYPESTATIC]], i32 0, i32 0), i64 [[VTINT]], i64 [[VTVALID]])
+ // DIAG-ABORT-NEXT: unreachable
+ // DIAG-RECOVER-NEXT: call void @__ubsan_handle_cfi_check_fail(i8* getelementptr inbounds ({{.*}} @[[BADTYPESTATIC]], i32 0, i32 0), i64 [[VTINT]], i64 [[VTVALID]])
+ // DIAG-RECOVER-NEXT: br label %[[CONTBB]]
+
+ // CFI: [[CONTBB]]
+ // CFI-NVT: [[PTR:%[^ ]*]] = load
+ // CFI-VT: [[PTRI8:%[^ ]*]] = extractvalue { i8*, i1 } [[PAIR]], 0
+ // CFI-VT: [[PTR:%[^ ]*]] = bitcast i8* [[PTRI8]] to
+ // CFI: call void [[PTR]]
+#line 123
+ a->f();
+}
+
+// ITANIUM: define internal void @_Z3df1PN12_GLOBAL__N_11DE
+// MS: define internal void @"?df1@@YAXPEAUD@?A0x{{[^@]*}}@@@Z"
+void df1(D *d) {
+ // TT-ITANIUM: {{%[^ ]*}} = call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata ![[DTYPE:[0-9]+]])
+ // TT-MS: {{%[^ ]*}} = call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"?AUA@@")
+ // TC-ITANIUM: {{%[^ ]*}} = call { i8*, i1 } @llvm.type.checked.load(i8* {{%[^ ]*}}, i32 0, metadata ![[DTYPE:[0-9]+]])
+ // TC-MS: {{%[^ ]*}} = call { i8*, i1 } @llvm.type.checked.load(i8* {{%[^ ]*}}, i32 0, metadata !"?AUA@@")
+ d->f();
+}
+
+// ITANIUM: define internal void @_Z3dg1PN12_GLOBAL__N_11DE
+// MS: define internal void @"?dg1@@YAXPEAUD@?A0x{{[^@]*}}@@@Z"
+void dg1(D *d) {
+ // TT-ITANIUM: {{%[^ ]*}} = call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1B")
+ // TT-MS: {{%[^ ]*}} = call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"?AUB@@")
+ // TC-ITANIUM: {{%[^ ]*}} = call { i8*, i1 } @llvm.type.checked.load(i8* {{%[^ ]*}}, i32 8, metadata !"_ZTS1B")
+ // TC-MS: {{%[^ ]*}} = call { i8*, i1 } @llvm.type.checked.load(i8* {{%[^ ]*}}, i32 0, metadata !"?AUB@@")
+ d->g();
+}
+
+// ITANIUM: define internal void @_Z3dh1PN12_GLOBAL__N_11DE
+// MS: define internal void @"?dh1@@YAXPEAUD@?A0x{{[^@]*}}@@@Z"
+void dh1(D *d) {
+ // TT-ITANIUM: {{%[^ ]*}} = call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata ![[DTYPE]])
+ // TT-MS: {{%[^ ]*}} = call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata ![[DTYPE:[0-9]+]])
+ // TC-ITANIUM: {{%[^ ]*}} = call { i8*, i1 } @llvm.type.checked.load(i8* {{%[^ ]*}}, i32 16, metadata ![[DTYPE]])
+ // TC-MS: {{%[^ ]*}} = call { i8*, i1 } @llvm.type.checked.load(i8* {{%[^ ]*}}, i32 8, metadata ![[DTYPE:[0-9]+]])
+ d->h();
+}
+
+// ITANIUM: define internal void @_Z3df2PN12_GLOBAL__N_11DE
+// MS: define internal void @"?df2@@YAXPEAUD@?A0x{{[^@]*}}@@@Z"
+__attribute__((no_sanitize("cfi")))
+void df2(D *d) {
+ // CFI-NVT-NOT: call i1 @llvm.type.test
+ // CFI-VT: [[P:%[^ ]*]] = call i1 @llvm.type.test
+ // CFI-VT: call void @llvm.assume(i1 [[P]])
+ d->f();
+}
+
+// ITANIUM: define internal void @_Z3df3PN12_GLOBAL__N_11DE
+// MS: define internal void @"?df3@@YAXPEAUD@?A0x{{[^@]*}}@@@Z"
+__attribute__((no_sanitize("address"))) __attribute__((no_sanitize("cfi-vcall")))
+void df3(D *d) {
+ // CFI-NVT-NOT: call i1 @llvm.type.test
+ // CFI-VT: [[P:%[^ ]*]] = call i1 @llvm.type.test
+ // CFI-VT: call void @llvm.assume(i1 [[P]])
+ d->f();
+}
+
+D d;
+
+void foo() {
+ df1(&d);
+ dg1(&d);
+ dh1(&d);
+ df2(&d);
+ df3(&d);
+
+ struct FA : A {
+ void f() {}
+ } fa;
+ af(&fa);
+}
+
+namespace test2 {
+
+struct A {
+ virtual void m_fn1();
+};
+struct B {
+ virtual void m_fn2();
+};
+struct C : B, A {};
+struct D : C {
+ void m_fn1();
+};
+
+// ITANIUM: define hidden void @_ZN5test21fEPNS_1DE
+// MS: define dso_local void @"?f@test2@@YAXPEAUD@1@@Z"
+void f(D *d) {
+ // TT-ITANIUM: {{%[^ ]*}} = call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTSN5test21DE")
+ // TT-MS: {{%[^ ]*}} = call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"?AUA@test2@@")
+ // TC-ITANIUM: {{%[^ ]*}} = call { i8*, i1 } @llvm.type.checked.load(i8* {{%[^ ]*}}, i32 8, metadata !"_ZTSN5test21DE")
+ // TC-MS: {{%[^ ]*}} = call { i8*, i1 } @llvm.type.checked.load(i8* {{%[^ ]*}}, i32 0, metadata !"?AUA@test2@@")
+ d->m_fn1();
+}
+
+}
+
+// ITANIUM: [[A16]] = !{i64 16, !"_ZTS1A"}
+// ITANIUM-DIAG: [[ALL16]] = !{i64 16, !"all-vtables"}
+// ITANIUM: [[AF16]] = !{i64 16, !"_ZTSM1AFvvE.virtual"}
+// ITANIUM: [[A32]] = !{i64 32, !"_ZTS1A"}
+// ITANIUM-DIAG: [[ALL32]] = !{i64 32, !"all-vtables"}
+// ITANIUM: [[AF32]] = !{i64 32, !"_ZTSM1AFvvE.virtual"}
+// ITANIUM: [[AF40]] = !{i64 40, !"_ZTSM1AFvvE.virtual"}
+// ITANIUM: [[AF48]] = !{i64 48, !"_ZTSM1AFvvE.virtual"}
+// ITANIUM: [[B32]] = !{i64 32, !"_ZTS1B"}
+// ITANIUM: [[BF32]] = !{i64 32, !"_ZTSM1BFvvE.virtual"}
+// ITANIUM: [[BF40]] = !{i64 40, !"_ZTSM1BFvvE.virtual"}
+// ITANIUM: [[BF48]] = !{i64 48, !"_ZTSM1BFvvE.virtual"}
+// ITANIUM: [[C32]] = !{i64 32, !"_ZTS1C"}
+// ITANIUM: [[CF32]] = !{i64 32, !"_ZTSM1CFvvE.virtual"}
+// ITANIUM: [[C88]] = !{i64 88, !"_ZTS1C"}
+// ITANIUM-DIAG: [[ALL88]] = !{i64 88, !"all-vtables"}
+// ITANIUM: [[CF40]] = !{i64 40, !"_ZTSM1CFvvE.virtual"}
+// ITANIUM: [[CF48]] = !{i64 48, !"_ZTSM1CFvvE.virtual"}
+// ITANIUM: [[D32]] = !{i64 32, [[D_ID:![0-9]+]]}
+// ITANIUM: [[D_ID]] = distinct !{}
+// ITANIUM: [[DF32]] = !{i64 32, [[DF_ID:![0-9]+]]}
+// ITANIUM: [[DF_ID]] = distinct !{}
+// ITANIUM: [[DF40]] = !{i64 40, [[DF_ID]]}
+// ITANIUM: [[DF48]] = !{i64 48, [[DF_ID]]}
+// ITANIUM: [[A64]] = !{i64 64, !"_ZTS1A"}
+// ITANIUM-DIAG: [[ALL64]] = !{i64 64, !"all-vtables"}
+// ITANIUM: [[AF64]] = !{i64 64, !"_ZTSM1AFvvE.virtual"}
+// ITANIUM: [[CF64]] = !{i64 64, !"_ZTSM1CFvvE.virtual"}
+// ITANIUM: [[FA16]] = !{i64 16, [[FA_ID:![0-9]+]]}
+// ITANIUM: [[FA_ID]] = distinct !{}
+// ITANIUM: [[FAF16]] = !{i64 16, [[FAF_ID:![0-9]+]]}
+// ITANIUM: [[FAF_ID]] = distinct !{}
+
+// MS: [[A8]] = !{i64 8, !"?AUA@@"}
+// MS: [[B8]] = !{i64 8, !"?AUB@@"}
+// MS: [[D8]] = !{i64 8, [[D_ID:![0-9]+]]}
+// MS: [[D_ID]] = distinct !{}
+// MS: [[FA8]] = !{i64 8, [[FA_ID:![0-9]+]]}
+// MS: [[FA_ID]] = distinct !{}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/type-traits.cpp b/src/llvm-project/clang/test/CodeGenCXX/type-traits.cpp
new file mode 100644
index 0000000..93cc6b5
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/type-traits.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -emit-llvm-only -verify %s
+// expected-no-diagnostics
+
+bool a() { return __is_pod(int); }
+
+bool b() { return __is_trivially_constructible(int, int, int); }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/type_visibility.cpp b/src/llvm-project/clang/test/CodeGenCXX/type_visibility.cpp
new file mode 100644
index 0000000..a7b7198
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/type_visibility.cpp
@@ -0,0 +1,170 @@
+// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-apple-darwin10 -emit-llvm -o %t.ll
+// RUN: FileCheck %s -check-prefix=FUNS < %t.ll
+// RUN: FileCheck %s -check-prefix=VARS < %t.ll
+// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-apple-darwin10 -fvisibility hidden -emit-llvm -o %t.ll
+// RUN: FileCheck %s -check-prefix=FUNS-HIDDEN < %t.ll
+// RUN: FileCheck %s -check-prefix=VARS-HIDDEN < %t.ll
+
+#define HIDDEN __attribute__((visibility("hidden")))
+#define PROTECTED __attribute__((visibility("protected")))
+#define DEFAULT __attribute__((visibility("default")))
+#define TYPE_HIDDEN __attribute__((type_visibility("hidden")))
+#define TYPE_PROTECTED __attribute__((type_visibility("protected")))
+#define TYPE_DEFAULT __attribute__((type_visibility("default")))
+
+// type_visibility is rdar://11880378
+
+#if !__has_attribute(type_visibility)
+#error No type_visibility attribute!
+#endif
+
+// The template tests come first because IR-gen reorders RTTI wierdly.
+namespace temp0 {
+ struct A;
+ template <class T> struct TYPE_DEFAULT B {
+ virtual void foo() {}
+ };
+
+ template struct B<A>;
+ // FUNS-LABEL: define weak_odr void @_ZN5temp01BINS_1AEE3fooEv(
+ // VARS: @_ZTVN5temp01BINS_1AEEE = weak_odr unnamed_addr constant
+ // VARS: @_ZTSN5temp01BINS_1AEEE = weak_odr constant
+ // VARS: @_ZTIN5temp01BINS_1AEEE = weak_odr constant
+ // FUNS-HIDDEN-LABEL: define weak_odr hidden void @_ZN5temp01BINS_1AEE3fooEv(
+ // VARS-HIDDEN: @_ZTVN5temp01BINS_1AEEE = weak_odr hidden unnamed_addr constant
+ // VARS-HIDDEN: @_ZTSN5temp01BINS_1AEEE = weak_odr hidden constant
+ // VARS-HIDDEN: @_ZTIN5temp01BINS_1AEEE = weak_odr hidden constant
+}
+
+namespace temp1 {
+ struct TYPE_DEFAULT A;
+ template <class T> struct TYPE_DEFAULT B {
+ virtual void foo() {}
+ };
+
+ template struct B<A>;
+ // FUNS-LABEL: define weak_odr void @_ZN5temp11BINS_1AEE3fooEv(
+ // VARS: @_ZTVN5temp11BINS_1AEEE = weak_odr unnamed_addr constant
+ // VARS: @_ZTSN5temp11BINS_1AEEE = weak_odr constant
+ // VARS: @_ZTIN5temp11BINS_1AEEE = weak_odr constant
+ // FUNS-HIDDEN-LABEL: define weak_odr hidden void @_ZN5temp11BINS_1AEE3fooEv(
+ // VARS-HIDDEN: @_ZTVN5temp11BINS_1AEEE = weak_odr unnamed_addr constant
+ // VARS-HIDDEN: @_ZTSN5temp11BINS_1AEEE = weak_odr constant
+ // VARS-HIDDEN: @_ZTIN5temp11BINS_1AEEE = weak_odr constant
+}
+
+namespace temp2 {
+ struct TYPE_DEFAULT A;
+ template <class T> struct B {
+ virtual void foo() {}
+ };
+
+ template struct B<A>;
+ // FUNS-LABEL: define weak_odr void @_ZN5temp21BINS_1AEE3fooEv(
+ // VARS: @_ZTVN5temp21BINS_1AEEE = weak_odr unnamed_addr constant
+ // VARS: @_ZTSN5temp21BINS_1AEEE = weak_odr constant
+ // VARS: @_ZTIN5temp21BINS_1AEEE = weak_odr constant
+ // FUNS-HIDDEN-LABEL: define weak_odr hidden void @_ZN5temp21BINS_1AEE3fooEv(
+ // VARS-HIDDEN: @_ZTVN5temp21BINS_1AEEE = weak_odr hidden unnamed_addr constant
+ // VARS-HIDDEN: @_ZTSN5temp21BINS_1AEEE = weak_odr hidden constant
+ // VARS-HIDDEN: @_ZTIN5temp21BINS_1AEEE = weak_odr hidden constant
+}
+
+namespace temp3 {
+ struct TYPE_HIDDEN A;
+ template <class T> struct TYPE_DEFAULT B {
+ virtual void foo() {}
+ };
+
+ template struct B<A>;
+ // FUNS-LABEL: define weak_odr hidden void @_ZN5temp31BINS_1AEE3fooEv(
+ // VARS: @_ZTVN5temp31BINS_1AEEE = weak_odr hidden unnamed_addr constant
+ // VARS: @_ZTSN5temp31BINS_1AEEE = weak_odr hidden constant
+ // VARS: @_ZTIN5temp31BINS_1AEEE = weak_odr hidden constant
+ // FUNS-HIDDEN-LABEL: define weak_odr hidden void @_ZN5temp31BINS_1AEE3fooEv(
+ // VARS-HIDDEN: @_ZTVN5temp31BINS_1AEEE = weak_odr hidden unnamed_addr constant
+ // VARS-HIDDEN: @_ZTSN5temp31BINS_1AEEE = weak_odr hidden constant
+ // VARS-HIDDEN: @_ZTIN5temp31BINS_1AEEE = weak_odr hidden constant
+}
+
+namespace temp4 {
+ struct TYPE_DEFAULT A;
+ template <class T> struct TYPE_HIDDEN B {
+ virtual void foo() {}
+ };
+
+ template struct B<A>;
+ // FUNS-LABEL: define weak_odr void @_ZN5temp41BINS_1AEE3fooEv(
+ // VARS: @_ZTVN5temp41BINS_1AEEE = weak_odr hidden unnamed_addr constant
+ // VARS: @_ZTSN5temp41BINS_1AEEE = weak_odr hidden constant
+ // VARS: @_ZTIN5temp41BINS_1AEEE = weak_odr hidden constant
+ // FUNS-HIDDEN-LABEL: define weak_odr hidden void @_ZN5temp41BINS_1AEE3fooEv(
+ // VARS-HIDDEN: @_ZTVN5temp41BINS_1AEEE = weak_odr hidden unnamed_addr constant
+ // VARS-HIDDEN: @_ZTSN5temp41BINS_1AEEE = weak_odr hidden constant
+ // VARS-HIDDEN: @_ZTIN5temp41BINS_1AEEE = weak_odr hidden constant
+}
+
+namespace type0 {
+ struct TYPE_DEFAULT A {
+ virtual void foo();
+ };
+
+ void A::foo() {}
+ // FUNS-LABEL: define void @_ZN5type01A3fooEv(
+ // VARS: @_ZTVN5type01AE = unnamed_addr constant
+ // VARS: @_ZTSN5type01AE = constant
+ // VARS: @_ZTIN5type01AE = constant
+ // FUNS-HIDDEN-LABEL: define hidden void @_ZN5type01A3fooEv(
+ // VARS-HIDDEN: @_ZTVN5type01AE = unnamed_addr constant
+ // VARS-HIDDEN: @_ZTSN5type01AE = constant
+ // VARS-HIDDEN: @_ZTIN5type01AE = constant
+}
+
+namespace type1 {
+ struct HIDDEN TYPE_DEFAULT A {
+ virtual void foo();
+ };
+
+ void A::foo() {}
+ // FUNS-LABEL: define hidden void @_ZN5type11A3fooEv(
+ // VARS: @_ZTVN5type11AE = unnamed_addr constant
+ // VARS: @_ZTSN5type11AE = constant
+ // VARS: @_ZTIN5type11AE = constant
+ // FUNS-HIDDEN-LABEL: define hidden void @_ZN5type11A3fooEv(
+ // VARS-HIDDEN: @_ZTVN5type11AE = unnamed_addr constant
+ // VARS-HIDDEN: @_ZTSN5type11AE = constant
+ // VARS-HIDDEN: @_ZTIN5type11AE = constant
+}
+
+namespace type2 {
+ struct TYPE_HIDDEN A {
+ virtual void foo();
+ };
+
+ void A::foo() {}
+ // FUNS-LABEL: define void @_ZN5type21A3fooEv(
+ // VARS: @_ZTVN5type21AE = hidden unnamed_addr constant
+ // VARS: @_ZTSN5type21AE = hidden constant
+ // VARS: @_ZTIN5type21AE = hidden constant
+ // FUNS-HIDDEN-LABEL: define hidden void @_ZN5type21A3fooEv(
+ // VARS-HIDDEN: @_ZTVN5type21AE = hidden unnamed_addr constant
+ // VARS-HIDDEN: @_ZTSN5type21AE = hidden constant
+ // VARS-HIDDEN: @_ZTIN5type21AE = hidden constant
+}
+
+namespace type3 {
+ struct DEFAULT TYPE_HIDDEN A {
+ virtual void foo();
+ };
+
+ void A::foo() {}
+ // FUNS-LABEL: define void @_ZN5type31A3fooEv(
+ // VARS: @_ZTVN5type31AE = hidden unnamed_addr constant
+ // VARS: @_ZTSN5type31AE = hidden constant
+ // VARS: @_ZTIN5type31AE = hidden constant
+ // FUNS-HIDDEN-LABEL: define void @_ZN5type31A3fooEv(
+ // VARS-HIDDEN: @_ZTVN5type31AE = hidden unnamed_addr constant
+ // VARS-HIDDEN: @_ZTSN5type31AE = hidden constant
+ // VARS-HIDDEN: @_ZTIN5type31AE = hidden constant
+}
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/typeid-cxx11.cpp b/src/llvm-project/clang/test/CodeGenCXX/typeid-cxx11.cpp
new file mode 100644
index 0000000..5c10ca5
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/typeid-cxx11.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -I%S %s -triple x86_64-apple-darwin10 -emit-llvm -std=c++11 -o - | FileCheck %s
+#include <typeinfo>
+
+namespace Test1 {
+
+struct Item {
+ const std::type_info &ti;
+ const char *name;
+ void *(*make)();
+};
+
+template<typename T> void *make_impl() { return new T; }
+template<typename T> constexpr Item item(const char *name) {
+ return { typeid(T), name, make_impl<T> };
+}
+
+struct A { virtual ~A(); };
+struct B : virtual A {};
+struct C { int n; };
+
+// CHECK: @_ZN5Test15itemsE = constant [4 x {{.*}}] [{{.*}} @_ZTIN5Test11AE {{.*}}, {{.*}}, {{.*}} @_ZN5Test19make_implINS_1AEEEPvv }, {{.*}} @_ZTIN5Test11BE {{.*}} @_ZN5Test19make_implINS_1BEEEPvv {{.*}} @_ZTIN5Test11CE {{.*}} @_ZN5Test19make_implINS_1CEEEPvv {{.*}} @_ZTIi {{.*}} @_ZN5Test19make_implIiEEPvv }]
+extern constexpr Item items[] = {
+ item<A>("A"), item<B>("B"), item<C>("C"), item<int>("int")
+};
+
+// CHECK: @_ZN5Test11xE = constant %"class.std::type_info"* bitcast ({{.*}}* @_ZTIN5Test11AE to %"class.std::type_info"*), align 8
+constexpr auto &x = items[0].ti;
+
+// CHECK: @_ZN5Test11yE = constant %"class.std::type_info"* bitcast ({{.*}}* @_ZTIN5Test11BE to %"class.std::type_info"*), align 8
+constexpr auto &y = typeid(B{});
+
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/typeid-should-throw.cpp b/src/llvm-project/clang/test/CodeGenCXX/typeid-should-throw.cpp
new file mode 100644
index 0000000..428c737
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/typeid-should-throw.cpp
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 %s -triple %itanium_abi_triple -Wno-unused-value -emit-llvm -o - -std=c++11 | FileCheck %s
+namespace std {
+struct type_info;
+}
+
+struct A {
+ virtual ~A();
+ operator bool();
+};
+struct B : A {};
+
+void f1(A *x) { typeid(false, *x); }
+// CHECK-LABEL: define {{.*}}void @_Z2f1P1A
+// CHECK: icmp eq {{.*}}, null
+// CHECK-NEXT: br i1
+
+void f2(bool b, A *x, A *y) { typeid(b ? *x : *y); }
+// CHECK-LABEL: define {{.*}}void @_Z2f2bP1AS0_
+// CHECK: icmp eq {{.*}}, null
+// CHECK-NEXT: br i1
+
+void f3(bool b, A *x, A &y) { typeid(b ? *x : y); }
+// CHECK-LABEL: define {{.*}}void @_Z2f3bP1ARS_
+// CHECK: icmp eq {{.*}}, null
+// CHECK-NEXT: br i1
+
+void f4(bool b, A &x, A *y) { typeid(b ? x : *y); }
+// CHECK-LABEL: define {{.*}}void @_Z2f4bR1APS_
+// CHECK: icmp eq {{.*}}, null
+// CHECK-NEXT: br i1
+
+void f5(volatile A *x) { typeid(*x); }
+// CHECK-LABEL: define {{.*}}void @_Z2f5PV1A
+// CHECK: icmp eq {{.*}}, null
+// CHECK-NEXT: br i1
+
+void f6(A *x) { typeid((B &)*(B *)x); }
+// CHECK-LABEL: define {{.*}}void @_Z2f6P1A
+// CHECK: icmp eq {{.*}}, null
+// CHECK-NEXT: br i1
+
+void f7(A *x) { typeid((*x)); }
+// CHECK-LABEL: define {{.*}}void @_Z2f7P1A
+// CHECK: icmp eq {{.*}}, null
+// CHECK-NEXT: br i1
+
+void f8(A *x) { typeid(x[0]); }
+// CHECK-LABEL: define {{.*}}void @_Z2f8P1A
+// CHECK: icmp eq {{.*}}, null
+// CHECK-NEXT: br i1
+
+void f9(A *x) { typeid(0[x]); }
+// CHECK-LABEL: define {{.*}}void @_Z2f9P1A
+// CHECK: icmp eq {{.*}}, null
+// CHECK-NEXT: br i1
+
+void f10(A *x, A *y) { typeid(*y ?: *x); }
+// CHECK-LABEL: define {{.*}}void @_Z3f10P1AS0_
+// CHECK: icmp eq {{.*}}, null
+// CHECK-NEXT: br i1
+
+void f11(A *x, A &y) { typeid(*x ?: y); }
+// CHECK-LABEL: define {{.*}}void @_Z3f11P1ARS_
+// CHECK: icmp eq {{.*}}, null
+// CHECK-NEXT: br i1
+
+void f12(A &x, A *y) { typeid(x ?: *y); }
+// CHECK-LABEL: define {{.*}}void @_Z3f12R1APS_
+// CHECK: icmp eq {{.*}}, null
+// CHECK-NEXT: br i1
+
+void f13(A &x, A &y) { typeid(x ?: y); }
+// CHECK-LABEL: define {{.*}}void @_Z3f13R1AS0_
+// CHECK-NOT: icmp eq {{.*}}, null
+
+void f14(A *x) { typeid((const A &)(A)*x); }
+// CHECK-LABEL: define {{.*}}void @_Z3f14P1A
+// CHECK-NOT: icmp eq {{.*}}, null
+
+void f15(A *x) { typeid((A &&)*(A *)nullptr); }
+// CHECK-LABEL: define {{.*}}void @_Z3f15P1A
+// CHECK-NOT: icmp eq {{.*}}, null
diff --git a/src/llvm-project/clang/test/CodeGenCXX/typeid.cpp b/src/llvm-project/clang/test/CodeGenCXX/typeid.cpp
new file mode 100644
index 0000000..364f058
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/typeid.cpp
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -I%S %s -triple x86_64-apple-darwin10 -emit-llvm -fcxx-exceptions -fexceptions -o - | FileCheck %s
+#include <typeinfo>
+
+namespace Test1 {
+
+// PR7400
+struct A { virtual void f(); };
+
+// CHECK: @_ZN5Test16int_tiE = constant %"class.std::type_info"* bitcast (i8** @_ZTIi to %"class.std::type_info"*), align 8
+const std::type_info &int_ti = typeid(int);
+
+// CHECK: @_ZN5Test14A_tiE = constant %"class.std::type_info"* bitcast (i8** @_ZTIN5Test11AE to %"class.std::type_info"*), align 8
+const std::type_info &A_ti = typeid(const volatile A &);
+
+volatile char c;
+
+// CHECK: @_ZN5Test14c_tiE = constant %"class.std::type_info"* bitcast (i8** @_ZTIc to %"class.std::type_info"*), align 8
+const std::type_info &c_ti = typeid(c);
+
+extern const double &d;
+
+// CHECK: @_ZN5Test14d_tiE = constant %"class.std::type_info"* bitcast (i8** @_ZTId to %"class.std::type_info"*), align 8
+const std::type_info &d_ti = typeid(d);
+
+extern A &a;
+
+// CHECK: @_ZN5Test14a_tiE = global
+const std::type_info &a_ti = typeid(a);
+
+// CHECK: @_ZN5Test18A10_c_tiE = constant %"class.std::type_info"* bitcast ({ i8*, i8* }* @_ZTIA10_c to %"class.std::type_info"*), align 8
+const std::type_info &A10_c_ti = typeid(char const[10]);
+
+// CHECK-LABEL: define i8* @_ZN5Test11fEv
+// CHECK-SAME: personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+const char *f() {
+ try {
+ // CHECK: br i1
+ // CHECK: invoke void @__cxa_bad_typeid() [[NR:#[0-9]+]]
+ return typeid(*static_cast<A *>(0)).name();
+ } catch (...) {
+ // CHECK: landingpad { i8*, i32 }
+ // CHECK-NEXT: catch i8* null
+ }
+
+ return 0;
+}
+
+}
+
+// CHECK: attributes [[NR]] = { noreturn }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/typeinfo b/src/llvm-project/clang/test/CodeGenCXX/typeinfo
new file mode 100644
index 0000000..7af23cf
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/typeinfo
@@ -0,0 +1,16 @@
+namespace std {
+ class type_info {
+ public:
+ virtual ~type_info();
+ const char* name() const { return __name; }
+ bool operator==(const type_info& __arg) const {
+ return __name == __arg.__name;
+ }
+
+ bool operator!=(const type_info& __arg) const {
+ return !operator==(__arg);
+ }
+ protected:
+ const char *__name;
+ };
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/ubsan-bitfields.cpp b/src/llvm-project/clang/test/CodeGenCXX/ubsan-bitfields.cpp
new file mode 100644
index 0000000..5595db0
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/ubsan-bitfields.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=bool,enum | FileCheck %s
+
+enum E {
+ a = 1,
+ b = 2,
+ c = 3
+};
+
+struct S {
+ E e1 : 10;
+};
+
+// CHECK-LABEL: define i32 @_Z4loadP1S
+E load(S *s) {
+ // CHECK: [[LOAD:%.*]] = load i16, i16* {{.*}}
+ // CHECK: [[CLEAR:%.*]] = and i16 [[LOAD]], 1023
+ // CHECK: [[CAST:%.*]] = zext i16 [[CLEAR]] to i32
+ // CHECK: icmp ule i32 [[CAST]], 3, !nosanitize
+ // CHECK: call void @__ubsan_handle_load_invalid_value
+ return s->e1;
+}
+
+struct Bool {
+ bool b1 : 1;
+ bool b2 : 7;
+ bool b3 : 16;
+};
+
+// CHECK-LABEL: define zeroext i1 @_Z13load_cpp_boolP4Bool
+bool load_cpp_bool(Bool *b) {
+ // CHECK-NOT: call void @__ubsan_handle_load_invalid_value
+ // CHECK-NOT: !nosanitize
+ return b->b1 || b->b2 || b->b3;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/ubsan-check-debuglocs.cpp b/src/llvm-project/clang/test/CodeGenCXX/ubsan-check-debuglocs.cpp
new file mode 100644
index 0000000..96a697a
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/ubsan-check-debuglocs.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited \
+// RUN: -fsanitize=null %s -o - | FileCheck %s
+
+// Check that santizer check calls have a !dbg location.
+// CHECK: define {{.*}}acquire{{.*}} !dbg
+// CHECK-NOT: define
+// CHECK: call void {{.*}}@__ubsan_handle_type_mismatch_v1
+// CHECK-SAME: !dbg
+
+struct SourceLocation {
+ SourceLocation acquire() {};
+};
+extern "C" void __ubsan_handle_type_mismatch_v1(SourceLocation *Loc);
+static void handleTypeMismatchImpl(SourceLocation *Loc) { Loc->acquire(); }
+void __ubsan_handle_type_mismatch_v1(SourceLocation *Loc) {
+ handleTypeMismatchImpl(Loc);
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/ubsan-ctor-srcloc.cpp b/src/llvm-project/clang/test/CodeGenCXX/ubsan-ctor-srcloc.cpp
new file mode 100644
index 0000000..da27a66
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/ubsan-ctor-srcloc.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-linux -emit-llvm -fsanitize=alignment -fblocks %s -o %t.ll
+// RUN: FileCheck -check-prefix=ZEROINIT < %t.ll %s
+// RUN: FileCheck -check-prefix=SRCLOC < %t.ll %s
+// ZEROINIT-NOT: @{{.+}} = private unnamed_addr global {{.+}} zeroinitializer
+
+struct A {
+ A(int);
+ int k;
+};
+
+struct B : A {
+ B();
+ B(const B &);
+// SRCLOC-DAG: @{{.+}} = private unnamed_addr global {{.+}} @.src, i32 [[@LINE+1]], i32 12 }
+ using A::A;
+ void f() const;
+};
+
+// SRCLOC-DAG: @{{.+}} = private unnamed_addr global {{.+}} @.src, i32 [[@LINE+1]], i32 10 }
+B::B() : A(1) {}
+
+void foo() {
+ B b(2);
+// SRCLOC-DAG: @{{.+}} = private unnamed_addr global {{.+}} @.src, i32 [[@LINE+1]], i32 5 }
+ ^{b.f();}();
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/ubsan-devirtualized-calls.cpp b/src/llvm-project/clang/test/CodeGenCXX/ubsan-devirtualized-calls.cpp
new file mode 100644
index 0000000..1510a4a
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/ubsan-devirtualized-calls.cpp
@@ -0,0 +1,88 @@
+// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -emit-llvm -fsanitize=null,vptr %s -o - | FileCheck %s
+
+struct Base1 {
+ virtual void f1() {}
+};
+
+struct Base2 {
+ virtual void f1() {}
+};
+
+struct Derived1 final : Base1 {
+ void f1() override {}
+};
+
+struct Derived2 final : Base1, Base2 {
+ void f1() override {}
+};
+
+struct Derived3 : Base1 {
+ void f1() override /* nofinal */ {}
+};
+
+struct Derived4 final : Base1 {
+ void f1() override final {}
+};
+
+// CHECK: [[UBSAN_TI_DERIVED1_1:@[0-9]+]] = private unnamed_addr global {{.*}} i8* bitcast {{.*}} @_ZTI8Derived1 to i8*
+// CHECK: [[UBSAN_TI_DERIVED2_1:@[0-9]+]] = private unnamed_addr global {{.*}} i8* bitcast {{.*}} @_ZTI8Derived2 to i8*
+// CHECK: [[UBSAN_TI_DERIVED2_2:@[0-9]+]] = private unnamed_addr global {{.*}} i8* bitcast {{.*}} @_ZTI8Derived2 to i8*
+// CHECK: [[UBSAN_TI_DERIVED3:@[0-9]+]] = private unnamed_addr global {{.*}} i8* bitcast {{.*}} @_ZTI8Derived3 to i8*
+// CHECK: [[UBSAN_TI_BASE1:@[0-9]+]] = private unnamed_addr global {{.*}} i8* bitcast {{.*}} @_ZTI5Base1 to i8*
+// CHECK: [[UBSAN_TI_DERIVED4_1:@[0-9]+]] = private unnamed_addr global {{.*}} i8* bitcast {{.*}} @_ZTI8Derived4 to i8*
+// CHECK: [[UBSAN_TI_DERIVED4_2:@[0-9]+]] = private unnamed_addr global {{.*}} i8* bitcast {{.*}} @_ZTI8Derived4 to i8*
+
+// CHECK-LABEL: define {{(dso_local )?}}void @_Z2t1v
+void t1() {
+ Derived1 d1;
+ static_cast<Base1 *>(&d1)->f1(); //< Devirt Base1::f1 to Derived1::f1.
+ // CHECK: %[[D1:[0-9]+]] = ptrtoint %struct.Derived1* %d1 to i{{[0-9]+}}, !nosanitize
+ // CHECK-NEXT: call void @__ubsan_handle_dynamic_type_cache{{[_a-z]*}}({{.*}} [[UBSAN_TI_DERIVED1_1]] {{.*}}, i{{[0-9]+}} %[[D1]]
+}
+
+// CHECK-LABEL: define {{(dso_local )?}}void @_Z2t2v
+void t2() {
+ Derived2 d2;
+ static_cast<Base1 *>(&d2)->f1(); //< Devirt Base1::f1 to Derived2::f1.
+ // CHECK: %[[D2_1:[0-9]+]] = ptrtoint %struct.Derived2* %d2 to i{{[0-9]+}}, !nosanitize
+ // CHECK-NEXT: call void @__ubsan_handle_dynamic_type_cache{{[_a-z]*}}({{.*}} [[UBSAN_TI_DERIVED2_1]] {{.*}}, i{{[0-9]+}} %[[D2_1]]
+}
+
+// CHECK-LABEL: define {{(dso_local )?}}void @_Z2t3v
+void t3() {
+ Derived2 d2;
+ static_cast<Base2 *>(&d2)->f1(); //< Devirt Base2::f1 to Derived2::f1.
+ // CHECK: %[[D2_2:[0-9]+]] = ptrtoint %struct.Derived2* %d2 to i{{[0-9]+}}, !nosanitize
+ // CHECK-NEXT: call void @__ubsan_handle_dynamic_type_cache{{[_a-z]*}}({{.*}} [[UBSAN_TI_DERIVED2_2]] {{.*}}, i{{[0-9]+}} %[[D2_2]]
+}
+
+// CHECK-LABEL: define {{(dso_local )?}}void @_Z2t4v
+void t4() {
+ Base1 p;
+ Derived3 *badp = static_cast<Derived3 *>(&p); //< Check that &p isa Derived3.
+ // CHECK: %[[P1:[0-9]+]] = ptrtoint %struct.Derived3* {{%[0-9]+}} to i{{[0-9]+}}, !nosanitize
+ // CHECK-NEXT: call void @__ubsan_handle_dynamic_type_cache{{[_a-z]*}}({{.*}} [[UBSAN_TI_DERIVED3]] {{.*}}, i{{[0-9]+}} %[[P1]]
+
+ static_cast<Base1 *>(badp)->f1(); //< No devirt, test 'badp isa Base1'.
+ // We were able to skip the null check on the first type check because 'p'
+ // is backed by an alloca. We can't skip the second null check because 'badp'
+ // is a (bitcast (load ...)).
+ // CHECK: call void @__ubsan_handle_type_mismatch
+ //
+ // CHECK: %[[BADP1:[0-9]+]] = ptrtoint %struct.Base1* {{%[0-9]+}} to i{{[0-9]+}}, !nosanitize
+ // CHECK-NEXT: call void @__ubsan_handle_dynamic_type_cache{{[_a-z]*}}({{.*}} [[UBSAN_TI_BASE1]] {{.*}}, i{{[0-9]+}} %[[BADP1]]
+}
+
+// CHECK-LABEL: define {{(dso_local )?}}void @_Z2t5v
+void t5() {
+ Base1 p;
+ Derived4 *badp = static_cast<Derived4 *>(&p); //< Check that &p isa Derived4.
+ // CHECK: %[[P1:[0-9]+]] = ptrtoint %struct.Derived4* {{%[0-9]+}} to i{{[0-9]+}}, !nosanitize
+ // CHECK-NEXT: call void @__ubsan_handle_dynamic_type_cache{{[_a-z]*}}({{.*}} [[UBSAN_TI_DERIVED4_1]] {{.*}}, i{{[0-9]+}} %[[P1]]
+
+ static_cast<Base1 *>(badp)->f1(); //< Devirt Base1::f1 to Derived4::f1.
+ // CHECK: call void @__ubsan_handle_type_mismatch
+ //
+ // CHECK: %[[BADP1:[0-9]+]] = ptrtoint %struct.Derived4* {{%[0-9]+}} to i{{[0-9]+}}, !nosanitize
+ // CHECK-NEXT: call void @__ubsan_handle_dynamic_type_cache{{[_a-z]*}}({{.*}} [[UBSAN_TI_DERIVED4_2]] {{.*}}, i{{[0-9]+}} %[[BADP1]]
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/ubsan-function-noexcept.cpp b/src/llvm-project/clang/test/CodeGenCXX/ubsan-function-noexcept.cpp
new file mode 100644
index 0000000..45c2764
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/ubsan-function-noexcept.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -std=c++17 -fsanitize=function -emit-llvm -triple x86_64-linux-gnu %s -o - | FileCheck %s
+
+// Check that typeinfo recorded in function prolog doesn't have "Do" noexcept
+// qualifier in its mangled name.
+// CHECK: @[[RTTI:[0-9]+]] = private constant i8* bitcast ({ i8*, i8* }* @_ZTIFvvE to i8*)
+// CHECK: define void @_Z1fv() #{{.*}} prologue <{ i32, i32 }> <{ i32 {{.*}}, i32 trunc (i64 sub (i64 ptrtoint (i8** @[[RTTI]] to i64), i64 ptrtoint (void ()* @_Z1fv to i64)) to i32) }>
+void f() noexcept {}
+
+// CHECK: define void @_Z1gPDoFvvE
+void g(void (*p)() noexcept) {
+ // Check that reference typeinfo at call site doesn't have "Do" noexcept
+ // qualifier in its mangled name, either.
+ // CHECK: icmp eq i8* %{{.*}}, bitcast ({ i8*, i8* }* @_ZTIFvvE to i8*), !nosanitize
+ p();
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/ubsan-global-alignment.cpp b/src/llvm-project/clang/test/CodeGenCXX/ubsan-global-alignment.cpp
new file mode 100644
index 0000000..67fcfd4
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/ubsan-global-alignment.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=alignment | FileCheck %s
+
+struct S {
+ int I;
+};
+
+extern S g_S;
+extern S array_S[];
+
+// CHECK-LABEL: define i32 @_Z18load_extern_global
+int load_extern_global() {
+ // FIXME: The IR builder constant-folds the alignment check away to 'true'
+ // here, so we never call the diagnostic. This is PR32630.
+ // CHECK-NOT: ptrtoint i32* {{.*}} to i32, !nosanitize
+ // CHECK: [[I:%.*]] = load i32, i32* getelementptr inbounds (%struct.S, %struct.S* @g_S, i32 0, i32 0), align 4
+ // CHECK-NEXT: ret i32 [[I]]
+ return g_S.I;
+}
+
+// CHECK-LABEL: define i32 @_Z22load_from_extern_array
+int load_from_extern_array(int I) {
+ // CHECK: [[I:%.*]] = getelementptr inbounds %struct.S, %struct.S* {{.*}}, i32 0, i32 0
+ // CHECK-NEXT: [[PTRTOINT:%.*]] = ptrtoint i32* [[I]] to i64, !nosanitize
+ // CHECK-NEXT: [[AND:%.*]] = and i64 [[PTRTOINT]], 3, !nosanitize
+ // CHECK-NEXT: [[ICMP:%.*]] = icmp eq i64 [[AND]], 0, !nosanitize
+ // CHECK-NEXT: br i1 [[ICMP]]
+ // CHECK: call void @__ubsan_handle_type_mismatch
+ return array_S[I].I;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/ubsan-new-checks.cpp b/src/llvm-project/clang/test/CodeGenCXX/ubsan-new-checks.cpp
new file mode 100644
index 0000000..019fcf1
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/ubsan-new-checks.cpp
@@ -0,0 +1,146 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -S -emit-llvm -fsanitize=alignment %s -o - | FileCheck %s
+
+struct alignas(32) S1 {
+ int x;
+ S1();
+};
+
+struct alignas(32) S2 {
+ int x;
+};
+
+struct alignas(32) S3 {
+ int x;
+ S3(int *p = new int[4]);
+};
+
+struct S4 : public S3 {
+ S4() : S3() {}
+};
+
+typedef __attribute__((ext_vector_type(2), aligned(32))) float float32x2_t;
+
+struct S5 {
+ float32x2_t x;
+};
+
+void *operator new (unsigned long, void *p) { return p; }
+void *operator new[] (unsigned long, void *p) { return p; }
+
+S1 *func_01() {
+ // CHECK-LABEL: define {{.*}} @_Z7func_01v
+ // CHECK: and i64 %{{.*}}, 31, !nosanitize
+ // CHECK: icmp eq i64 %{{.*}}, 0, !nosanitize
+ // CHECK: call void @_ZN2S1C1Ev(
+ // CHECK-NOT: and i64 %{{.*}}, 31
+ // CHECK: ret %struct.S1*
+ return new S1[20];
+}
+
+S2 *func_02() {
+ // CHECK-LABEL: define {{.*}} @_Z7func_02v
+ // CHECK: and i64 %{{.*}}, 31, !nosanitize
+ // CHECK: icmp eq i64 %{{.*}}, 0, !nosanitize
+ // CHECK: ret %struct.S2*
+ return new S2;
+}
+
+S2 *func_03() {
+ // CHECK-LABEL: define {{.*}} @_Z7func_03v
+ // CHECK: and i64 %{{.*}}, 31, !nosanitize
+ // CHECK: icmp eq i64 %{{.*}}, 0, !nosanitize
+ // CHECK-NOT: and i64 %{{.*}}, 31
+ // CHECK: ret %struct.S2*
+ return new S2[20];
+}
+
+float32x2_t *func_04() {
+ // CHECK-LABEL: define {{.*}} @_Z7func_04v
+ // CHECK: and i64 %{{.*}}, 31, !nosanitize
+ // CHECK: icmp eq i64 %{{.*}}, 0, !nosanitize
+ // CHECK: ret <2 x float>*
+ return new float32x2_t;
+}
+
+float32x2_t *func_05() {
+ // CHECK-LABEL: define {{.*}} @_Z7func_05v
+ // CHECK: and i64 %{{.*}}, 31, !nosanitize
+ // CHECK: icmp eq i64 %{{.*}}, 0, !nosanitize
+ // CHECK-NOT: and i64 %{{.*}}, 31
+ // CHECK: ret <2 x float>*
+ return new float32x2_t[20];
+}
+
+S3 *func_07() {
+ // CHECK-LABEL: define {{.*}} @_Z7func_07v
+ // CHECK: and i64 %{{.*}}, 31, !nosanitize
+ // CHECK: icmp eq i64 %{{.*}}, 0, !nosanitize
+ // CHECK: and i64 %{{.*}}, 3, !nosanitize
+ // CHECK: icmp eq i64 %{{.*}}, 0, !nosanitize
+ // CHECK: ret %struct.S3*
+ return new S3;
+}
+
+S3 *func_08() {
+ // CHECK-LABEL: define {{.*}} @_Z7func_08v
+ // CHECK: and i64 %{{.*}}, 31, !nosanitize
+ // CHECK: icmp eq i64 %{{.*}}, 0, !nosanitize
+ // CHECK: and i64 %{{.*}}, 3, !nosanitize
+ // CHECK: icmp eq i64 %{{.*}}, 0, !nosanitize
+ // CHECK: ret %struct.S3*
+ return new S3[10];
+}
+
+
+S2 *func_10(void *p) {
+ // CHECK-LABEL: define {{.*}} @_Z7func_10Pv
+ // CHECK: and i64 %{{.*}}, 31, !nosanitize
+ // CHECK: icmp eq i64 %{{.*}}, 0, !nosanitize
+ // CHECK: ret %struct.S2*
+ return new(p) S2;
+}
+
+S2 *func_11(void *p) {
+ // CHECK-LABEL: define {{.*}} @_Z7func_11Pv
+ // CHECK: and i64 %{{.*}}, 31, !nosanitize
+ // CHECK: icmp eq i64 %{{.*}}, 0, !nosanitize
+ // CHECK-NOT: and i64 %{{.*}}, 31, !nosanitize
+ // CHECK-NOT: icmp eq i64 %{{.*}}, 0, !nosanitize
+ // CHECK: ret %struct.S2*
+ return new(p) S2[10];
+}
+
+float32x2_t *func_12() {
+ // CHECK-LABEL: define {{.*}} @_Z7func_12v
+ // CHECK: and i64 %{{.*}}, 31, !nosanitize
+ // CHECK: icmp eq i64 %{{.*}}, 0, !nosanitize
+ // CHECK: ret <2 x float>*
+ return new float32x2_t;
+}
+
+float32x2_t *func_13() {
+ // CHECK-LABEL: define {{.*}} @_Z7func_13v
+ // CHECK: and i64 %{{.*}}, 31, !nosanitize
+ // CHECK: icmp eq i64 %{{.*}}, 0, !nosanitize
+ // CHECK-NOT: and i64 %{{.*}}, 31
+ // CHECK: ret <2 x float>*
+ return new float32x2_t[20];
+}
+
+S4 *func_14() {
+ // CHECK-LABEL: define {{.*}} @_Z7func_14v
+ // CHECK: and i64 %{{.*}}, 31, !nosanitize
+ // CHECK: icmp eq i64 %{{.*}}, 0, !nosanitize
+ // CHECK-NOT: and i64 %{{.*}}, 31
+ // CHECK: ret %struct.S4*
+ return new S4;
+}
+
+S5 *func_15(const S5 *ptr) {
+ // CHECK-LABEL: define {{.*}} @_Z7func_15PK2S5
+ // CHECK: and i64 %{{.*}}, 31, !nosanitize
+ // CHECK: icmp eq i64 %{{.*}}, 0, !nosanitize
+ // CHECK-NOT: and i64
+ // CHECK: ret %struct.S5*
+ return new S5(*ptr);
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/ubsan-nullability-assign.cpp b/src/llvm-project/clang/test/CodeGenCXX/ubsan-nullability-assign.cpp
new file mode 100644
index 0000000..3f85c88
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/ubsan-nullability-assign.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -x c++ -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=nullability-assign | FileCheck %s
+
+struct S1 {
+ int *_Nonnull p;
+};
+
+struct S2 {
+ S1 s1;
+};
+
+union U1 {
+ S1 s1;
+ S2 s2;
+};
+
+// CHECK-LABEL: define void @{{.*}}f1
+void f1(int *p) {
+ U1 u;
+
+ // CHECK: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize
+ // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
+ // CHECK: call void @__ubsan_handle_type_mismatch{{.*}} !nosanitize
+ // CHECK: store
+ u.s1.p = p;
+
+ // CHECK: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize
+ // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
+ // CHECK: call void @__ubsan_handle_type_mismatch{{.*}} !nosanitize
+ // CHECK: store
+ u.s2.s1.p = p;
+
+ // CHECK-NOT: __ubsan_handle_type_mismatch
+ // CHECK-NOT: store
+ // CHECK: ret void
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/ubsan-suppress-checks.cpp b/src/llvm-project/clang/test/CodeGenCXX/ubsan-suppress-checks.cpp
new file mode 100644
index 0000000..fa7ea29
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/ubsan-suppress-checks.cpp
@@ -0,0 +1,244 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=alignment | FileCheck %s --check-prefixes=CHECK,ALIGN
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=null | FileCheck %s --check-prefixes=CHECK,NULL
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=alignment,null -DCHECK_LAMBDA | FileCheck %s --check-prefixes=LAMBDA
+
+// CHECK-LABEL: define void @_Z22load_non_null_pointersv
+void load_non_null_pointers() {
+ int var;
+ var = *&var;
+
+ int arr[1];
+ arr[0] = arr[0];
+
+ char c = "foo"[0];
+
+ // CHECK-NOT: and i64 {{.*}}, !nosanitize
+ // CHECK-NOT: icmp ne {{.*}}, null, !nosanitize
+ // CHECK: ret void
+}
+
+// CHECK-LABEL: define void @_Z31use_us16_aligned_array_elementsv
+void use_us16_aligned_array_elements() {
+ static const unsigned short Arr[] = {0, 1, 2};
+ auto use_array = [](const unsigned short(&X)[3]) -> void {};
+ use_array(Arr);
+
+ // CHECK-NOT: br i1 true
+ // ALIGN-NOT: call void @__ubsan_handle_type_mismatch
+ // CHECK: ret void
+}
+
+struct A {
+ int foo;
+
+ // CHECK-LABEL: define linkonce_odr void @_ZN1A10do_nothingEv
+ void do_nothing() {
+ // ALIGN: %[[THISINT1:[0-9]+]] = ptrtoint %struct.A* %{{.*}} to i64, !nosanitize
+ // ALIGN: and i64 %[[THISINT1]], 3, !nosanitize
+ // NULL: icmp ne %struct.A* %[[THIS1:[a-z0-9]+]], null, !nosanitize
+ // NULL: ptrtoint %struct.A* %[[THIS1]] to i64, !nosanitize
+ // CHECK: call void @__ubsan_handle_type_mismatch
+ // CHECK-NOT: call void @__ubsan_handle_type_mismatch
+ // CHECK: ret void
+ }
+
+#ifdef CHECK_LAMBDA
+ // LAMBDA-LABEL: define linkonce_odr void @_ZN1A22do_nothing_with_lambdaEv
+ void do_nothing_with_lambda() {
+ // LAMBDA: icmp ne %struct.A* %[[THIS2:[a-z0-9]+]], null, !nosanitize
+ // LAMBDA: %[[THISINT2:[0-9]+]] = ptrtoint %struct.A* %[[THIS2]] to i64, !nosanitize
+ // LAMBDA: and i64 %[[THISINT2]], 3, !nosanitize
+ // LAMBDA: call void @__ubsan_handle_type_mismatch
+
+ auto f = [&] {
+ foo = 0;
+ };
+ f();
+
+ // LAMBDA-NOT: call void @__ubsan_handle_type_mismatch
+ // LAMBDA: ret void
+ }
+
+// Check the IR for the lambda:
+//
+// LAMBDA-LABEL: define linkonce_odr void @_ZZN1A22do_nothing_with_lambdaEvENKUlvE_clEv
+// LAMBDA: call void @__ubsan_handle_type_mismatch
+// LAMBDA-NOT: call void @__ubsan_handle_type_mismatch
+// LAMBDA: ret void
+#endif
+
+ // CHECK-LABEL: define linkonce_odr i32 @_ZN1A11load_memberEv
+ int load_member() {
+ // ALIGN: %[[THISINT3:[0-9]+]] = ptrtoint %struct.A* %{{.*}} to i64, !nosanitize
+ // ALIGN: and i64 %[[THISINT3]], 3, !nosanitize
+ // NULL: icmp ne %struct.A* %[[THIS3:[a-z0-9]+]], null, !nosanitize
+ // NULL: ptrtoint %struct.A* %[[THIS3]] to i64, !nosanitize
+ // CHECK: call void @__ubsan_handle_type_mismatch
+ // CHECK-NOT: call void @__ubsan_handle_type_mismatch
+ return foo;
+ // CHECK: ret i32
+ }
+
+ // CHECK-LABEL: define linkonce_odr i32 @_ZN1A11call_methodEv
+ int call_method() {
+ // ALIGN: %[[THISINT4:[0-9]+]] = ptrtoint %struct.A* %{{.*}} to i64, !nosanitize
+ // ALIGN: and i64 %[[THISINT4]], 3, !nosanitize
+ // NULL: icmp ne %struct.A* %[[THIS4:[a-z0-9]+]], null, !nosanitize
+ // NULL: ptrtoint %struct.A* %[[THIS4]] to i64, !nosanitize
+ // CHECK: call void @__ubsan_handle_type_mismatch
+ // CHECK-NOT: call void @__ubsan_handle_type_mismatch
+ return load_member();
+ // CHECK: ret i32
+ }
+
+ // CHECK-LABEL: define linkonce_odr void @_ZN1A15assign_member_1Ev
+ void assign_member_1() {
+ // ALIGN: %[[THISINT5:[0-9]+]] = ptrtoint %struct.A* %{{.*}} to i64, !nosanitize
+ // ALIGN: and i64 %[[THISINT5]], 3, !nosanitize
+ // NULL: icmp ne %struct.A* %[[THIS5:[a-z0-9]+]], null, !nosanitize
+ // NULL: ptrtoint %struct.A* %[[THIS5]] to i64, !nosanitize
+ // CHECK: call void @__ubsan_handle_type_mismatch
+ // CHECK-NOT: call void @__ubsan_handle_type_mismatch
+ foo = 0;
+ // CHECK: ret void
+ }
+
+ // CHECK-LABEL: define linkonce_odr void @_ZN1A15assign_member_2Ev
+ void assign_member_2() {
+ // ALIGN: %[[THISINT6:[0-9]+]] = ptrtoint %struct.A* %{{.*}} to i64, !nosanitize
+ // ALIGN: and i64 %[[THISINT6]], 3, !nosanitize
+ // NULL: icmp ne %struct.A* %[[THIS6:[a-z0-9]+]], null, !nosanitize
+ // NULL: ptrtoint %struct.A* %[[THIS6]] to i64, !nosanitize
+ // CHECK: call void @__ubsan_handle_type_mismatch
+ // CHECK-NOT: call void @__ubsan_handle_type_mismatch
+ (__extension__ (this))->foo = 0;
+ // CHECK: ret void
+ }
+
+ // CHECK-LABEL: define linkonce_odr void @_ZNK1A15assign_member_3Ev
+ void assign_member_3() const {
+ // ALIGN: %[[THISINT7:[0-9]+]] = ptrtoint %struct.A* %{{.*}} to i64, !nosanitize
+ // ALIGN: and i64 %[[THISINT7]], 3, !nosanitize
+ // NULL: icmp ne %struct.A* %[[THIS7:[a-z0-9]+]], null, !nosanitize
+ // NULL: ptrtoint %struct.A* %[[THIS7]] to i64, !nosanitize
+ // CHECK: call void @__ubsan_handle_type_mismatch
+ // CHECK-NOT: call void @__ubsan_handle_type_mismatch
+ const_cast<A *>(this)->foo = 0;
+ // CHECK: ret void
+ }
+
+ // CHECK-LABEL: define linkonce_odr i32 @_ZN1A22call_through_referenceERS_
+ static int call_through_reference(A &a) {
+ // ALIGN: %[[OBJINT:[0-9]+]] = ptrtoint %struct.A* %{{.*}} to i64, !nosanitize
+ // ALIGN: and i64 %[[OBJINT]], 3, !nosanitize
+ // ALIGN: call void @__ubsan_handle_type_mismatch
+ // NULL-NOT: call void @__ubsan_handle_type_mismatch
+ return a.load_member();
+ // CHECK: ret i32
+ }
+
+ // CHECK-LABEL: define linkonce_odr i32 @_ZN1A20call_through_pointerEPS_
+ static int call_through_pointer(A *a) {
+ // CHECK: call void @__ubsan_handle_type_mismatch
+ return a->load_member();
+ // CHECK: ret i32
+ }
+};
+
+struct B {
+ operator A*() const { return nullptr; }
+
+ // CHECK-LABEL: define linkonce_odr i32 @_ZN1B11load_memberEPS_
+ static int load_member(B *bp) {
+ // Check &b before converting it to an A*.
+ // CHECK: call void @__ubsan_handle_type_mismatch
+ //
+ // Check the result of the conversion before using it.
+ // NULL: call void @__ubsan_handle_type_mismatch
+ //
+ // CHECK-NOT: call void @__ubsan_handle_type_mismatch
+ return static_cast<A *>(*bp)->load_member();
+ // CHECK: ret i32
+ }
+};
+
+struct Base {
+ int foo;
+
+ virtual int load_member_1() = 0;
+};
+
+struct Derived : public Base {
+ int bar;
+
+ // CHECK-LABEL: define linkonce_odr i32 @_ZN7Derived13load_member_2Ev
+ int load_member_2() {
+ // ALIGN: %[[THISINT8:[0-9]+]] = ptrtoint %struct.Derived* %{{.*}} to i64, !nosanitize
+ // ALIGN: and i64 %[[THISINT8]], 7, !nosanitize
+ // ALIGN: call void @__ubsan_handle_type_mismatch
+ // NULL: icmp ne %struct.Derived* %[[THIS8:[a-z0-9]+]], null, !nosanitize
+ // NULL: ptrtoint %struct.Derived* %[[THIS8]] to i64, !nosanitize
+ // CHECK: call void @__ubsan_handle_type_mismatch
+ //
+ // Check the result of the cast before using it.
+ // CHECK: call void @__ubsan_handle_type_mismatch
+ //
+ // CHECK-NOT: call void @__ubsan_handle_type_mismatch
+ return dynamic_cast<Base *>(this)->load_member_1();
+ // CHECK: ret i32
+ }
+
+ // CHECK-LABEL: define linkonce_odr i32 @_ZN7Derived13load_member_3Ev
+ int load_member_3() {
+ // ALIGN: %[[THISINT9:[0-9]+]] = ptrtoint %struct.Derived* %{{.*}} to i64, !nosanitize
+ // ALIGN: and i64 %[[THISINT9]], 7, !nosanitize
+ // ALIGN: call void @__ubsan_handle_type_mismatch
+ // ALIGN: call void @__ubsan_handle_type_mismatch
+ // NULL: icmp ne %struct.Derived* %[[THIS9:[a-z0-9]+]], null, !nosanitize
+ // NULL: ptrtoint %struct.Derived* %[[THIS9]] to i64, !nosanitize
+ // CHECK: call void @__ubsan_handle_type_mismatch
+ // CHECK-NOT: call void @__ubsan_handle_type_mismatch
+ return reinterpret_cast<Derived *>(static_cast<Base *>(this))->foo;
+ // CHECK: ret i32
+ }
+
+ // CHECK-LABEL: define linkonce_odr i32 @_ZN7Derived13load_member_1Ev
+ int load_member_1() override {
+ // ALIGN: %[[THISINT10:[0-9]+]] = ptrtoint %struct.Derived* %{{.*}} to i64, !nosanitize
+ // ALIGN: and i64 %[[THISINT10]], 7, !nosanitize
+ // ALIGN: call void @__ubsan_handle_type_mismatch
+ // NULL: icmp ne %struct.Derived* %[[THIS10:[a-z0-9]+]], null, !nosanitize
+ // NULL: ptrtoint %struct.Derived* %[[THIS10]] to i64, !nosanitize
+ // CHECK: call void @__ubsan_handle_type_mismatch
+ // CHECK-NOT: call void @__ubsan_handle_type_mismatch
+ return foo + bar;
+ // CHECK: ret i32
+ }
+};
+
+void force_irgen() {
+ A *a;
+ a->do_nothing();
+#ifdef CHECK_LAMBDA
+ a->do_nothing_with_lambda();
+#endif
+ a->load_member();
+ a->call_method();
+ a->assign_member_1();
+ a->assign_member_2();
+ a->assign_member_3();
+ A::call_through_reference(*a);
+ A::call_through_pointer(a);
+
+ B::load_member(nullptr);
+
+ Base *b = new Derived;
+ b->load_member_1();
+
+ Derived *d;
+ d->load_member_2();
+ d->load_member_3();
+
+ load_non_null_pointers();
+ use_us16_aligned_array_elements();
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/ubsan-type-checks.cpp b/src/llvm-project/clang/test/CodeGenCXX/ubsan-type-checks.cpp
new file mode 100644
index 0000000..e53ab24
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/ubsan-type-checks.cpp
@@ -0,0 +1,85 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=alignment | FileCheck %s -check-prefixes=ALIGN,COMMON
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=null | FileCheck %s -check-prefixes=NULL,COMMON
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=object-size | FileCheck %s -check-prefixes=OBJSIZE,COMMON
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=null,vptr | FileCheck %s -check-prefixes=VPTR
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=vptr | FileCheck %s -check-prefixes=VPTR_NO_NULL
+
+struct A {
+ // COMMON-LABEL: define linkonce_odr void @_ZN1A10do_nothingEv
+ void do_nothing() {
+ // ALIGN-NOT: ptrtoint %struct.A* %{{.*}} to i64, !nosanitize
+
+ // NULL: icmp ne %struct.A* %{{.*}}, null, !nosanitize
+
+ // OBJSIZE-NOT: call i64 @llvm.objectsize
+ }
+};
+
+struct B {
+ int x;
+
+ // COMMON-LABEL: define linkonce_odr void @_ZN1B10do_nothingEv
+ void do_nothing() {
+ // ALIGN: ptrtoint %struct.B* %{{.*}} to i64, !nosanitize
+ // ALIGN: and i64 %{{.*}}, 3, !nosanitize
+
+ // NULL: icmp ne %struct.B* %{{.*}}, null, !nosanitize
+
+ // OBJSIZE-NOT: call i64 @llvm.objectsize
+ // OBJSIZE: ret void
+ }
+};
+
+struct Animal {
+ virtual const char *speak() = 0;
+};
+
+struct Cat : Animal {
+ const char *speak() override { return "meow"; }
+};
+
+struct Dog : Animal {
+ const char *speak() override { return "woof"; }
+};
+
+// VPTR-LABEL: define void @_Z12invalid_castP3Cat
+void invalid_cast(Cat *cat = nullptr) {
+ // If -fsanitize=null is available, we'll reuse its check:
+ //
+ // VPTR: [[ICMP:%.*]] = icmp ne %struct.Dog* {{.*}}, null
+ // VPTR-NEXT: br i1 [[ICMP]]
+ // VPTR: call void @__ubsan_handle_type_mismatch
+ // VPTR-NOT: icmp ne %struct.Dog* {{.*}}, null
+ // VPTR: br i1 [[ICMP]]
+ // VPTR: call void @__ubsan_handle_dynamic_type_cache_miss
+ //
+ // Fall back to the vptr sanitizer's null check when -fsanitize=null isn't
+ // available.
+ //
+ // VPTR_NO_NULL-NOT: call void @__ubsan_handle_type_mismatch
+ // VPTR_NO_NULL: [[ICMP:%.*]] = icmp ne %struct.Dog* {{.*}}, null
+ // VPTR_NO_NULL-NEXT: br i1 [[ICMP]]
+ // VPTR_NO_NULL: call void @__ubsan_handle_dynamic_type_cache_miss
+ auto *badDog = reinterpret_cast<Dog *>(cat);
+ badDog->speak();
+}
+
+// VPTR_NO_NULL-LABEL: define void @_Z13invalid_cast2v
+void invalid_cast2() {
+ // We've got a pointer to an alloca, so there's no run-time null check needed.
+ // VPTR_NO_NULL-NOT: call void @__ubsan_handle_type_mismatch
+ // VPTR_NO_NULL: call void @__ubsan_handle_dynamic_type_cache_miss
+ Cat cat;
+ cat.speak();
+}
+
+int main() {
+ A a;
+ a.do_nothing();
+
+ B b;
+ b.do_nothing();
+
+ invalid_cast();
+ return 0;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/ubsan-unreachable.cpp b/src/llvm-project/clang/test/CodeGenCXX/ubsan-unreachable.cpp
new file mode 100644
index 0000000..32a7804
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/ubsan-unreachable.cpp
@@ -0,0 +1,81 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=unreachable | FileCheck %s
+
+extern void __attribute__((noreturn)) abort();
+
+// CHECK-LABEL: define void @_Z14calls_noreturnv
+void calls_noreturn() {
+ abort();
+
+ // Check that there are no attributes on the call site.
+ // CHECK-NOT: call void @_Z5abortv{{.*}}#
+
+ // CHECK: __ubsan_handle_builtin_unreachable
+ // CHECK: unreachable
+}
+
+struct A {
+ // CHECK: declare void @_Z5abortv{{.*}} [[ABORT_ATTR:#[0-9]+]]
+
+ // CHECK-LABEL: define linkonce_odr void @_ZN1A5call1Ev
+ void call1() {
+ // CHECK-NOT: call void @_ZN1A16does_not_return2Ev{{.*}}#
+ does_not_return2();
+
+ // CHECK: __ubsan_handle_builtin_unreachable
+ // CHECK: unreachable
+ }
+
+ // Test static members.
+ static void __attribute__((noreturn)) does_not_return1() {
+ // CHECK-NOT: call void @_Z5abortv{{.*}}#
+ abort();
+ }
+
+ // CHECK-LABEL: define linkonce_odr void @_ZN1A5call2Ev
+ void call2() {
+ // CHECK-NOT: call void @_ZN1A16does_not_return1Ev{{.*}}#
+ does_not_return1();
+
+ // CHECK: __ubsan_handle_builtin_unreachable
+ // CHECK: unreachable
+ }
+
+ // Test calls through pointers to non-static member functions.
+ typedef void __attribute__((noreturn)) (A::*MemFn)();
+
+ // CHECK-LABEL: define linkonce_odr void @_ZN1A5call3Ev
+ void call3() {
+ MemFn MF = &A::does_not_return2;
+ (this->*MF)();
+
+ // CHECK-NOT: call void %{{.*}}#
+ // CHECK: __ubsan_handle_builtin_unreachable
+ // CHECK: unreachable
+ }
+
+ // Test regular members.
+ // CHECK-LABEL: define linkonce_odr void @_ZN1A16does_not_return2Ev({{.*}})
+ // CHECK-SAME: [[DOES_NOT_RETURN_ATTR:#[0-9]+]]
+ void __attribute__((noreturn)) does_not_return2() {
+ // CHECK-NOT: call void @_Z5abortv(){{.*}}#
+ abort();
+
+ // CHECK: call void @__ubsan_handle_builtin_unreachable
+ // CHECK: unreachable
+
+ // CHECK: call void @__ubsan_handle_builtin_unreachable
+ // CHECK: unreachable
+ }
+};
+
+// CHECK: define linkonce_odr void @_ZN1A16does_not_return1Ev() [[DOES_NOT_RETURN_ATTR]]
+
+void force_irgen() {
+ A a;
+ a.call1();
+ a.call2();
+ a.call3();
+}
+
+// CHECK-NOT: [[ABORT_ATTR]] = {{[^}]+}}noreturn
+// CHECK-NOT: [[DOES_NOT_RETURN_ATTR]] = {{[^}]+}}noreturn
diff --git a/src/llvm-project/clang/test/CodeGenCXX/ubsan-vtable-checks.cpp b/src/llvm-project/clang/test/CodeGenCXX/ubsan-vtable-checks.cpp
new file mode 100644
index 0000000..ec4a21a
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/ubsan-vtable-checks.cpp
@@ -0,0 +1,54 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-linux -emit-llvm -fsanitize=null %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NULL --check-prefix=ITANIUM
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows -emit-llvm -fsanitize=null %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NULL --check-prefix=MSABI
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-linux -emit-llvm -fsanitize=null,vptr %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-VPTR --check-prefix=ITANIUM
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows -emit-llvm -fsanitize=null,vptr %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-VPTR --check-prefix=MSABI --check-prefix=CHECK-VPTR-MS
+struct T {
+ virtual ~T() {}
+ virtual int v() { return 1; }
+};
+
+struct U : T {
+ ~U();
+ virtual int v() { return 2; }
+};
+
+U::~U() {}
+
+// CHECK-VPTR-MS: @__ubsan_vptr_type_cache = external dso_local
+
+// ITANIUM: define i32 @_Z5get_vP1T
+// MSABI: define dso_local i32 @"?get_v
+int get_v(T* t) {
+ // First, we check that vtable is not loaded before a type check.
+ // CHECK-NULL-NOT: load {{.*}} (%struct.T*{{.*}})**, {{.*}} (%struct.T*{{.*}})***
+ // CHECK-NULL: [[UBSAN_CMP_RES:%[0-9]+]] = icmp ne %struct.T* %{{[_a-z0-9]+}}, null
+ // CHECK-NULL-NEXT: br i1 [[UBSAN_CMP_RES]], label %{{.*}}, label %{{.*}}
+ // CHECK-NULL: call void @__ubsan_handle_type_mismatch_v1_abort
+ // Second, we check that vtable is actually loaded once the type check is done.
+ // CHECK-NULL: load {{.*}} (%struct.T*{{.*}})**, {{.*}} (%struct.T*{{.*}})***
+ return t->v();
+}
+
+// ITANIUM: define void @_Z9delete_itP1T
+// MSABI: define dso_local void @"?delete_it
+void delete_it(T *t) {
+ // First, we check that vtable is not loaded before a type check.
+ // CHECK-VPTR-NOT: load {{.*}} (%struct.T*{{.*}})**, {{.*}} (%struct.T*{{.*}})***
+ // CHECK-VPTR: br i1 {{.*}} label %{{.*}}
+ // CHECK-VPTR: call void @__ubsan_handle_dynamic_type_cache_miss_abort
+ // Second, we check that vtable is actually loaded once the type check is done.
+ // CHECK-VPTR: load {{.*}} (%struct.T*{{.*}})**, {{.*}} (%struct.T*{{.*}})***
+ delete t;
+}
+
+// ITANIUM: define %struct.U* @_Z7dyncastP1T
+// MSABI: define dso_local %struct.U* @"?dyncast
+U* dyncast(T *t) {
+ // First, we check that dynamic_cast is not called before a type check.
+ // CHECK-VPTR-NOT: call i8* @__{{dynamic_cast|RTDynamicCast}}
+ // CHECK-VPTR: br i1 {{.*}} label %{{.*}}
+ // CHECK-VPTR: call void @__ubsan_handle_dynamic_type_cache_miss_abort
+ // Second, we check that dynamic_cast is actually called once the type check is done.
+ // CHECK-VPTR: call i8* @__{{dynamic_cast|RTDynamicCast}}
+ return dynamic_cast<U*>(t);
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/unaligned-member-qualifier.cpp b/src/llvm-project/clang/test/CodeGenCXX/unaligned-member-qualifier.cpp
new file mode 100644
index 0000000..57cfbd9
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/unaligned-member-qualifier.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -fms-extensions -emit-llvm %s -o- | FileCheck %s
+
+struct A {
+ void foo() __unaligned;
+ void foo() const __unaligned;
+ void foo() volatile __unaligned;
+ void foo() const volatile __unaligned;
+};
+
+void A::foo() __unaligned {}
+// CHECK: define {{(dso_local )?}}[[THISCALL:(x86_thiscallcc )?]]void @_ZNU11__unaligned1A3fooEv(
+
+void A::foo() const __unaligned {}
+// CHECK: define {{(dso_local )?}}[[THISCALL]]void @_ZNU11__unalignedK1A3fooEv(
+
+void A::foo() volatile __unaligned {}
+// CHECK: define {{(dso_local )?}}[[THISCALL]]void @_ZNU11__unalignedV1A3fooEv(
+
+void A::foo() const volatile __unaligned {}
+// CHECK: define {{(dso_local )?}}[[THISCALL]]void @_ZNU11__unalignedVK1A3fooEv(
diff --git a/src/llvm-project/clang/test/CodeGenCXX/unaligned.cpp b/src/llvm-project/clang/test/CodeGenCXX/unaligned.cpp
new file mode 100644
index 0000000..95549d3
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/unaligned.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -x c++ -std=c++11 -triple x86_64-unknown-linux-gnu -fms-extensions -emit-llvm < %s | FileCheck %s
+
+int foo() {
+ // CHECK: ret i32 1
+ return alignof(__unaligned int);
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/uncode-string.cpp b/src/llvm-project/clang/test/CodeGenCXX/uncode-string.cpp
new file mode 100644
index 0000000..1d83999
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/uncode-string.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
+// rdar://8360841
+
+wchar_t s[] = L"\u2722";
+
+// CHECK: @s = global [2 x i32] [i32 10018, i32 0], align 4
diff --git a/src/llvm-project/clang/test/CodeGenCXX/uncopyable-args.cpp b/src/llvm-project/clang/test/CodeGenCXX/uncopyable-args.cpp
new file mode 100644
index 0000000..baada1c
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/uncopyable-args.cpp
@@ -0,0 +1,370 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=NEWABI
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown -fclang-abi-compat=4.0 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=OLDABI
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-scei-ps4 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=OLDABI
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows-msvc -emit-llvm -o - %s -fms-compatibility -fms-compatibility-version=18 | FileCheck %s -check-prefix=WIN64 -check-prefix=WIN64-18
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows-msvc -emit-llvm -o - %s -fms-compatibility -fms-compatibility-version=19 | FileCheck %s -check-prefix=WIN64 -check-prefix=WIN64-19
+
+namespace trivial {
+// Trivial structs should be passed directly.
+struct A {
+ void *p;
+};
+void foo(A);
+void bar() {
+ foo({});
+}
+// CHECK-LABEL: define void @_ZN7trivial3barEv()
+// CHECK: alloca %"struct.trivial::A"
+// CHECK: load i8*, i8**
+// CHECK: call void @_ZN7trivial3fooENS_1AE(i8* %{{.*}})
+// CHECK-LABEL: declare void @_ZN7trivial3fooENS_1AE(i8*)
+
+// WIN64-LABEL: declare dso_local void @"?foo@trivial@@YAXUA@1@@Z"(i64)
+}
+
+namespace default_ctor {
+struct A {
+ A();
+ void *p;
+};
+void foo(A);
+void bar() {
+ // Core issue 1590. We can pass this type in registers, even though C++
+ // normally doesn't permit copies when using braced initialization.
+ foo({});
+}
+// CHECK-LABEL: define void @_ZN12default_ctor3barEv()
+// CHECK: alloca %"struct.default_ctor::A"
+// CHECK: call void @_Z{{.*}}C1Ev(
+// CHECK: load i8*, i8**
+// CHECK: call void @_ZN12default_ctor3fooENS_1AE(i8* %{{.*}})
+// CHECK-LABEL: declare void @_ZN12default_ctor3fooENS_1AE(i8*)
+
+// WIN64-LABEL: declare dso_local void @"?foo@default_ctor@@YAXUA@1@@Z"(i64)
+}
+
+namespace move_ctor {
+// The presence of a move constructor implicitly deletes the trivial copy ctor
+// and means that we have to pass this struct by address.
+struct A {
+ A();
+ A(A &&o);
+ void *p;
+};
+void foo(A);
+void bar() {
+ foo({});
+}
+// CHECK-LABEL: define void @_ZN9move_ctor3barEv()
+// CHECK: call void @_Z{{.*}}C1Ev(
+// CHECK-NOT: call
+// NEWABI: call void @_ZN9move_ctor3fooENS_1AE(%"struct.move_ctor::A"* %{{.*}})
+// OLDABI: call void @_ZN9move_ctor3fooENS_1AE(i8* %{{.*}})
+// NEWABI-LABEL: declare void @_ZN9move_ctor3fooENS_1AE(%"struct.move_ctor::A"*)
+// OLDABI-LABEL: declare void @_ZN9move_ctor3fooENS_1AE(i8*)
+
+// WIN64-LABEL: declare dso_local void @"?foo@move_ctor@@YAXUA@1@@Z"(%"struct.move_ctor::A"*)
+}
+
+namespace all_deleted {
+struct A {
+ A();
+ A(const A &o) = delete;
+ A(A &&o) = delete;
+ void *p;
+};
+void foo(A);
+void bar() {
+ foo({});
+}
+// CHECK-LABEL: define void @_ZN11all_deleted3barEv()
+// CHECK: call void @_Z{{.*}}C1Ev(
+// CHECK-NOT: call
+// NEWABI: call void @_ZN11all_deleted3fooENS_1AE(%"struct.all_deleted::A"* %{{.*}})
+// OLDABI: call void @_ZN11all_deleted3fooENS_1AE(i8* %{{.*}})
+// NEWABI-LABEL: declare void @_ZN11all_deleted3fooENS_1AE(%"struct.all_deleted::A"*)
+// OLDABI-LABEL: declare void @_ZN11all_deleted3fooENS_1AE(i8*)
+
+// WIN64-LABEL: declare dso_local void @"?foo@all_deleted@@YAXUA@1@@Z"(%"struct.all_deleted::A"*)
+}
+
+namespace implicitly_deleted {
+struct A {
+ A();
+ A &operator=(A &&o);
+ void *p;
+};
+void foo(A);
+void bar() {
+ foo({});
+}
+// CHECK-LABEL: define void @_ZN18implicitly_deleted3barEv()
+// CHECK: call void @_Z{{.*}}C1Ev(
+// CHECK-NOT: call
+// NEWABI: call void @_ZN18implicitly_deleted3fooENS_1AE(%"struct.implicitly_deleted::A"* %{{.*}})
+// OLDABI: call void @_ZN18implicitly_deleted3fooENS_1AE(i8* %{{.*}})
+// NEWABI-LABEL: declare void @_ZN18implicitly_deleted3fooENS_1AE(%"struct.implicitly_deleted::A"*)
+// OLDABI-LABEL: declare void @_ZN18implicitly_deleted3fooENS_1AE(i8*)
+
+// In MSVC 2013, the copy ctor is not deleted by a move assignment. In MSVC 2015, it is.
+// WIN64-18-LABEL: declare dso_local void @"?foo@implicitly_deleted@@YAXUA@1@@Z"(i64
+// WIN64-19-LABEL: declare dso_local void @"?foo@implicitly_deleted@@YAXUA@1@@Z"(%"struct.implicitly_deleted::A"*)
+}
+
+namespace one_deleted {
+struct A {
+ A();
+ A(A &&o) = delete;
+ void *p;
+};
+void foo(A);
+void bar() {
+ foo({});
+}
+// CHECK-LABEL: define void @_ZN11one_deleted3barEv()
+// CHECK: call void @_Z{{.*}}C1Ev(
+// CHECK-NOT: call
+// NEWABI: call void @_ZN11one_deleted3fooENS_1AE(%"struct.one_deleted::A"* %{{.*}})
+// OLDABI: call void @_ZN11one_deleted3fooENS_1AE(i8* %{{.*}})
+// NEWABI-LABEL: declare void @_ZN11one_deleted3fooENS_1AE(%"struct.one_deleted::A"*)
+// OLDABI-LABEL: declare void @_ZN11one_deleted3fooENS_1AE(i8*)
+
+// WIN64-LABEL: declare dso_local void @"?foo@one_deleted@@YAXUA@1@@Z"(%"struct.one_deleted::A"*)
+}
+
+namespace copy_defaulted {
+struct A {
+ A();
+ A(const A &o) = default;
+ A(A &&o) = delete;
+ void *p;
+};
+void foo(A);
+void bar() {
+ foo({});
+}
+// CHECK-LABEL: define void @_ZN14copy_defaulted3barEv()
+// CHECK: call void @_Z{{.*}}C1Ev(
+// CHECK: load i8*, i8**
+// CHECK: call void @_ZN14copy_defaulted3fooENS_1AE(i8* %{{.*}})
+// CHECK-LABEL: declare void @_ZN14copy_defaulted3fooENS_1AE(i8*)
+
+// WIN64-LABEL: declare dso_local void @"?foo@copy_defaulted@@YAXUA@1@@Z"(i64)
+}
+
+namespace move_defaulted {
+struct A {
+ A();
+ A(const A &o) = delete;
+ A(A &&o) = default;
+ void *p;
+};
+void foo(A);
+void bar() {
+ foo({});
+}
+// CHECK-LABEL: define void @_ZN14move_defaulted3barEv()
+// CHECK: call void @_Z{{.*}}C1Ev(
+// CHECK: load i8*, i8**
+// CHECK: call void @_ZN14move_defaulted3fooENS_1AE(i8* %{{.*}})
+// CHECK-LABEL: declare void @_ZN14move_defaulted3fooENS_1AE(i8*)
+
+// WIN64-LABEL: declare dso_local void @"?foo@move_defaulted@@YAXUA@1@@Z"(%"struct.move_defaulted::A"*)
+}
+
+namespace trivial_defaulted {
+struct A {
+ A();
+ A(const A &o) = default;
+ void *p;
+};
+void foo(A);
+void bar() {
+ foo({});
+}
+// CHECK-LABEL: define void @_ZN17trivial_defaulted3barEv()
+// CHECK: call void @_Z{{.*}}C1Ev(
+// CHECK: load i8*, i8**
+// CHECK: call void @_ZN17trivial_defaulted3fooENS_1AE(i8* %{{.*}})
+// CHECK-LABEL: declare void @_ZN17trivial_defaulted3fooENS_1AE(i8*)
+
+// WIN64-LABEL: declare dso_local void @"?foo@trivial_defaulted@@YAXUA@1@@Z"(i64)
+}
+
+namespace two_copy_ctors {
+struct A {
+ A();
+ A(const A &) = default;
+ A(const A &, int = 0);
+ void *p;
+};
+struct B : A {};
+
+void foo(B);
+void bar() {
+ foo({});
+}
+// CHECK-LABEL: define void @_ZN14two_copy_ctors3barEv()
+// CHECK: call void @_Z{{.*}}C1Ev(
+// NEWABI: call void @_ZN14two_copy_ctors3fooENS_1BE(%"struct.two_copy_ctors::B"* %{{.*}})
+// OLDABI: call void @_ZN14two_copy_ctors3fooENS_1BE(%"struct.two_copy_ctors::B"* byval
+// NEWABI-LABEL: declare void @_ZN14two_copy_ctors3fooENS_1BE(%"struct.two_copy_ctors::B"*)
+// OLDABI-LABEL: declare void @_ZN14two_copy_ctors3fooENS_1BE(%"struct.two_copy_ctors::B"* byval
+
+// WIN64-LABEL: declare dso_local void @"?foo@two_copy_ctors@@YAXUB@1@@Z"(%"struct.two_copy_ctors::B"*)
+}
+
+namespace definition_only {
+struct A {
+ A();
+ A(A &&o);
+ void *p;
+};
+void *foo(A a) { return a.p; }
+// NEWABI-LABEL: define i8* @_ZN15definition_only3fooENS_1AE(%"struct.definition_only::A"*
+// OLDABI-LABEL: define i8* @_ZN15definition_only3fooENS_1AE(i8*
+// WIN64-LABEL: define dso_local i8* @"?foo@definition_only@@YAPEAXUA@1@@Z"(%"struct.definition_only::A"*
+}
+
+namespace deleted_by_member {
+struct B {
+ B();
+ B(B &&o);
+ void *p;
+};
+struct A {
+ A();
+ B b;
+};
+void *foo(A a) { return a.b.p; }
+// NEWABI-LABEL: define i8* @_ZN17deleted_by_member3fooENS_1AE(%"struct.deleted_by_member::A"*
+// OLDABI-LABEL: define i8* @_ZN17deleted_by_member3fooENS_1AE(i8*
+// WIN64-LABEL: define dso_local i8* @"?foo@deleted_by_member@@YAPEAXUA@1@@Z"(%"struct.deleted_by_member::A"*
+}
+
+namespace deleted_by_base {
+struct B {
+ B();
+ B(B &&o);
+ void *p;
+};
+struct A : B {
+ A();
+};
+void *foo(A a) { return a.p; }
+// NEWABI-LABEL: define i8* @_ZN15deleted_by_base3fooENS_1AE(%"struct.deleted_by_base::A"*
+// OLDABI-LABEL: define i8* @_ZN15deleted_by_base3fooENS_1AE(i8*
+// WIN64-LABEL: define dso_local i8* @"?foo@deleted_by_base@@YAPEAXUA@1@@Z"(%"struct.deleted_by_base::A"*
+}
+
+namespace deleted_by_member_copy {
+struct B {
+ B();
+ B(const B &o) = delete;
+ void *p;
+};
+struct A {
+ A();
+ B b;
+};
+void *foo(A a) { return a.b.p; }
+// NEWABI-LABEL: define i8* @_ZN22deleted_by_member_copy3fooENS_1AE(%"struct.deleted_by_member_copy::A"*
+// OLDABI-LABEL: define i8* @_ZN22deleted_by_member_copy3fooENS_1AE(i8*
+// WIN64-LABEL: define dso_local i8* @"?foo@deleted_by_member_copy@@YAPEAXUA@1@@Z"(%"struct.deleted_by_member_copy::A"*
+}
+
+namespace deleted_by_base_copy {
+struct B {
+ B();
+ B(const B &o) = delete;
+ void *p;
+};
+struct A : B {
+ A();
+};
+void *foo(A a) { return a.p; }
+// NEWABI-LABEL: define i8* @_ZN20deleted_by_base_copy3fooENS_1AE(%"struct.deleted_by_base_copy::A"*
+// OLDABI-LABEL: define i8* @_ZN20deleted_by_base_copy3fooENS_1AE(i8*
+// WIN64-LABEL: define dso_local i8* @"?foo@deleted_by_base_copy@@YAPEAXUA@1@@Z"(%"struct.deleted_by_base_copy::A"*
+}
+
+namespace explicit_delete {
+struct A {
+ A();
+ A(const A &o) = delete;
+ void *p;
+};
+// NEWABI-LABEL: define i8* @_ZN15explicit_delete3fooENS_1AE(%"struct.explicit_delete::A"*
+// OLDABI-LABEL: define i8* @_ZN15explicit_delete3fooENS_1AE(i8*
+// WIN64-LABEL: define dso_local i8* @"?foo@explicit_delete@@YAPEAXUA@1@@Z"(%"struct.explicit_delete::A"*
+void *foo(A a) { return a.p; }
+}
+
+namespace implicitly_deleted_copy_ctor {
+struct A {
+ // No move ctor due to copy assignment.
+ A &operator=(const A&);
+ // Deleted copy ctor due to rvalue ref member.
+ int &&ref;
+};
+// NEWABI-LABEL: define {{.*}} @_ZN28implicitly_deleted_copy_ctor3fooENS_1AE(%"struct.implicitly_deleted_copy_ctor::A"*
+// OLDABI-LABEL: define {{.*}} @_ZN28implicitly_deleted_copy_ctor3fooENS_1AE(i32*
+// WIN64-LABEL: define {{.*}} @"?foo@implicitly_deleted_copy_ctor@@YAAEAHUA@1@@Z"(%"struct.implicitly_deleted_copy_ctor::A"*
+int &foo(A a) { return a.ref; }
+
+struct B {
+ // Passed direct: has non-deleted trivial copy ctor.
+ B &operator=(const B&);
+ int &ref;
+};
+int &foo(B b) { return b.ref; }
+// CHECK-LABEL: define {{.*}} @_ZN28implicitly_deleted_copy_ctor3fooENS_1BE(i32*
+// WIN64-LABEL: define {{.*}} @"?foo@implicitly_deleted_copy_ctor@@YAAEAHUB@1@@Z"(i64
+
+struct X { X(const X&); };
+struct Y { Y(const Y&) = default; };
+
+union C {
+ C &operator=(const C&);
+ // Passed indirect: copy ctor deleted due to variant member with nontrivial copy ctor.
+ X x;
+ int n;
+};
+int foo(C c) { return c.n; }
+// CHECK-LABEL: define {{.*}} @_ZN28implicitly_deleted_copy_ctor3fooENS_1CE(%"union.implicitly_deleted_copy_ctor::C"*
+// WIN64-LABEL: define {{.*}} @"?foo@implicitly_deleted_copy_ctor@@YAHTC@1@@Z"(%"union.implicitly_deleted_copy_ctor::C"*
+
+struct D {
+ D &operator=(const D&);
+ // Passed indirect: copy ctor deleted due to variant member with nontrivial copy ctor.
+ union {
+ X x;
+ int n;
+ };
+};
+int foo(D d) { return d.n; }
+// CHECK-LABEL: define {{.*}} @_ZN28implicitly_deleted_copy_ctor3fooENS_1DE(%"struct.implicitly_deleted_copy_ctor::D"*
+// WIN64-LABEL: define {{.*}} @"?foo@implicitly_deleted_copy_ctor@@YAHUD@1@@Z"(%"struct.implicitly_deleted_copy_ctor::D"*
+
+union E {
+ // Passed direct: has non-deleted trivial copy ctor.
+ E &operator=(const E&);
+ Y y;
+ int n;
+};
+int foo(E e) { return e.n; }
+// CHECK-LABEL: define {{.*}} @_ZN28implicitly_deleted_copy_ctor3fooENS_1EE(i32
+// WIN64-LABEL: define {{.*}} @"?foo@implicitly_deleted_copy_ctor@@YAHTE@1@@Z"(i32
+
+struct F {
+ // Passed direct: has non-deleted trivial copy ctor.
+ F &operator=(const F&);
+ union {
+ Y y;
+ int n;
+ };
+};
+int foo(F f) { return f.n; }
+// CHECK-LABEL: define {{.*}} @_ZN28implicitly_deleted_copy_ctor3fooENS_1FE(i32
+// WIN64-LABEL: define {{.*}} @"?foo@implicitly_deleted_copy_ctor@@YAHUF@1@@Z"(i32
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/union-dtor.cpp b/src/llvm-project/clang/test/CodeGenCXX/union-dtor.cpp
new file mode 100644
index 0000000..a0b822a
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/union-dtor.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -std=c++11 %s -S -o - -emit-llvm | FileCheck %s
+
+// PR10304: destructors should not call destructors for variant members.
+
+template<bool b = false>
+struct Foo {
+ Foo() { static_assert(b, "Foo::Foo used"); }
+ ~Foo() { static_assert(b, "Foo::~Foo used"); }
+};
+
+struct Bar {
+ Bar();
+ ~Bar();
+};
+
+union FooBar {
+ FooBar() {}
+ ~FooBar() {}
+ Foo<> foo;
+ Bar bar;
+};
+
+struct Variant {
+ Variant() {}
+ ~Variant() {}
+ union {
+ Foo<> foo;
+ Bar bar;
+ };
+};
+
+FooBar foobar;
+Variant variant;
+
+// The ctor and dtor of Foo<> and Bar should not be mentioned in the resulting
+// code.
+//
+// CHECK-NOT: 3FooILb1EEC1
+// CHECK-NOT: 3BarC1
+//
+// CHECK-NOT: 3FooILb1EED1
+// CHECK-NOT: 3BarD1
diff --git a/src/llvm-project/clang/test/CodeGenCXX/union-tbaa2.cpp b/src/llvm-project/clang/test/CodeGenCXX/union-tbaa2.cpp
new file mode 100644
index 0000000..d3e3740
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/union-tbaa2.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 %s -O2 -std=c++11 -triple x86_64-unknown-linux-gnu -target-cpu x86-64 -target-feature +sse4.2 -target-feature +avx -emit-llvm -o - | FileCheck %s
+
+// Testcase from llvm.org/PR32056
+
+extern "C" int printf (const char *__restrict __format, ...);
+
+typedef double __m256d __attribute__((__vector_size__(32)));
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__,
+ __target__("avx")))
+_mm256_setr_pd(double __a, double __b, double __c, double __d) {
+ return (__m256d){ __a, __b, __c, __d };
+}
+
+struct A {
+ A () {
+// Check that the TBAA information generated for the stores to the
+// union members is based on the omnipotent char.
+// CHECK: store <4 x double>
+// CHECK: tbaa ![[OCPATH:[0-9]+]]
+// CHECK: store <4 x double>
+// CHECK: tbaa ![[OCPATH]]
+// CHECK: call
+ a = _mm256_setr_pd(0.0, 1.0, 2.0, 3.0);
+ b = _mm256_setr_pd(4.0, 5.0, 6.0, 7.0);
+ }
+
+ const double *begin() { return c; }
+ const double *end() { return c+8; }
+
+ union {
+ struct { __m256d a, b; };
+ double c[8];
+ };
+};
+
+int main(int argc, char *argv[]) {
+ A a;
+ for (double value : a)
+ printf("%f ", value);
+ return 0;
+}
+
+// CHECK-DAG: ![[CHAR:[0-9]+]] = !{!"omnipotent char"
+// CHECK-DAG: ![[OCPATH]] = !{![[CHAR]], ![[CHAR]], i64 0}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/unknown-anytype.cpp b/src/llvm-project/clang/test/CodeGenCXX/unknown-anytype.cpp
new file mode 100644
index 0000000..42ed472
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/unknown-anytype.cpp
@@ -0,0 +1,125 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -funknown-anytype -emit-llvm -o %t %s
+// RUN: FileCheck -check-prefix COMMON %s < %t
+// RUN: FileCheck -check-prefix X86_64 %s < %t
+// RUN: %clang_cc1 -triple i386-apple-darwin10 -funknown-anytype -emit-llvm -o %t %s
+// RUN: FileCheck -check-prefix COMMON %s < %t
+// RUN: FileCheck -check-prefix I386 %s < %t
+
+// x86-64 is the special case here because of its variadic convention.
+// We want to ensure that it always uses a variadic convention even if
+// other platforms do not.
+// rdar://13731520
+
+int test0() {
+ extern __unknown_anytype test0_any;
+ // COMMON: load i32, i32* @test0_any
+ return (int) test0_any;
+}
+
+int test1() {
+ extern __unknown_anytype test1_any();
+ // COMMON: call i32 @_Z9test1_anyv()
+ return (int) test1_any();
+}
+
+extern "C" __unknown_anytype test2_any(...);
+float test2() {
+ // X86_64: call float (double, ...) @test2_any(double {{[^,]+}})
+ // I386: call float (double, ...) @test2_any(double {{[^,]+}})
+ return (float) test2_any(0.5f);
+}
+
+extern "C" __unknown_anytype test2a_any(...);
+float test2a() {
+ // X86_64: call float (float, ...) @test2a_any(float {{[^,]+}})
+ // I386: call float (float, ...) @test2a_any(float {{[^,]+}})
+ return (float) test2a_any((float) 0.5f);
+}
+
+float test3() {
+ extern __unknown_anytype test3_any;
+ // COMMON: [[FN:%.*]] = load float (i32)*, float (i32)** @test3_any,
+ // COMMON: call float [[FN]](i32 5)
+ return ((float(*)(int)) test3_any)(5);
+}
+
+namespace test4 {
+ extern __unknown_anytype test4_any1;
+ extern __unknown_anytype test4_any2;
+
+ int test() {
+ // COMMON: load i32, i32* @_ZN5test410test4_any1E
+ // COMMON: load i8, i8* @_ZN5test410test4_any2E
+ return (int) test4_any1 + (char) test4_any2;
+ }
+}
+
+extern "C" __unknown_anytype test5_any();
+void test5() {
+ // COMMON: call void @test5_any()
+ return (void) test5_any();
+}
+
+extern "C" __unknown_anytype test6_any(float *);
+long test6() {
+ // COMMON: call i64 @test6_any(float* null)
+ return (long long) test6_any(0);
+}
+
+struct Test7 {
+ ~Test7();
+};
+extern "C" __unknown_anytype test7_any(int);
+Test7 test7() {
+ // COMMON: call void @test7_any({{%.*}}* sret {{%.*}}, i32 5)
+ return (Test7) test7_any(5);
+}
+
+struct Test8 {
+ __unknown_anytype foo();
+ __unknown_anytype foo(int);
+
+ void test();
+};
+void Test8::test() {
+ float f;
+ // COMMON: call i32 @_ZN5Test83fooEv(
+ f = (int) foo();
+ // COMMON: call i32 @_ZN5Test83fooEi(
+ f = (int) foo(5);
+ // COMMON: call i32 @_ZN5Test83fooEv(
+ f = (float) this->foo();
+ // COMMON: call i32 @_ZN5Test83fooEi(
+ f = (float) this->foo(5);
+}
+void test8(Test8 *p) {
+ double d;
+ // COMMON: call i32 @_ZN5Test83fooEv(
+ d = (double) p->foo();
+ // COMMON: call i32 @_ZN5Test83fooEi(
+ d = (double) p->foo(5);
+ // COMMON: call i32 @_ZN5Test83fooEv(
+ d = (bool) (*p).foo();
+ // COMMON: call i32 @_ZN5Test83fooEi(
+ d = (bool) (*p).foo(5);
+}
+
+extern "C" __unknown_anytype test9_foo;
+void *test9() {
+ // COMMON: ret i8* bitcast (i32* @test9_foo to i8*)
+ return (int*) &test9_foo;
+}
+
+// Don't explode on this.
+extern "C" __unknown_anytype test10_any(...);
+void test10() {
+ (void) test10_any(), (void) test10_any();
+}
+
+extern "C" __unknown_anytype malloc(...);
+void test11() {
+ void *s = (void*)malloc(12);
+ // COMMON: call i8* (i32, ...) @malloc(i32 12)
+ void *d = (void*)malloc(435);
+ // COMMON: call i8* (i32, ...) @malloc(i32 435)
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/value-init.cpp b/src/llvm-project/clang/test/CodeGenCXX/value-init.cpp
new file mode 100644
index 0000000..8d76fc5
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/value-init.cpp
@@ -0,0 +1,341 @@
+// RUN: %clang_cc1 -std=c++98 %s -triple x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-CXX98
+// RUN: %clang_cc1 -std=c++17 %s -triple x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-CXX17
+
+struct A {
+ virtual ~A();
+};
+
+struct B : A { };
+
+struct C {
+ int i;
+ B b;
+};
+
+// CHECK: _Z15test_value_initv
+void test_value_init() {
+ // This value initialization requires zero initialization of the 'B'
+ // subobject followed by a call to its constructor.
+ // PR5800
+
+ // CHECK: store i32 17
+ // CHECK: call void @llvm.memset.p0i8.i64
+ // CHECK: call void @_ZN1BC1Ev
+ C c = { 17 } ;
+ // CHECK: call void @_ZN1CD1Ev
+}
+
+enum enum_type { negative_number = -1, magic_number = 42 };
+
+class enum_holder
+{
+ enum_type m_enum;
+
+public:
+ enum_holder() : m_enum(magic_number) { }
+};
+
+struct enum_holder_and_int
+{
+ enum_holder e;
+ int i;
+};
+
+// CHECK: _Z24test_enum_holder_and_intv()
+void test_enum_holder_and_int() {
+ // CHECK: alloca
+ // CHECK-NEXT: bitcast
+ // CHECK-NEXT: call void @llvm.memset
+ // CHECK-NEXT: call void @_ZN19enum_holder_and_intC1Ev
+ enum_holder_and_int();
+ // CHECK-NEXT: ret void
+}
+
+// PR7834: don't crash.
+namespace test1 {
+ struct A {
+ int A::*f;
+ A();
+ A(const A&);
+ A &operator=(const A &);
+ };
+
+ struct B {
+ A base;
+ };
+
+ void foo() {
+ B();
+ }
+}
+
+namespace ptrmem {
+ struct S {
+ int mem1;
+ int S::*mem2;
+ };
+
+ // CHECK-LABEL: define i32 @_ZN6ptrmem4testEPNS_1SE
+ int test(S *s) {
+ // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
+ // CHECK: getelementptr
+ // CHECK: ret
+ return s->*S().mem2;
+ }
+}
+
+namespace PR9801 {
+
+struct Test {
+ Test() : i(10) {}
+ Test(int i) : i(i) {}
+ int i;
+private:
+ int j;
+};
+
+struct Test2 {
+ Test t;
+};
+
+struct Test3 : public Test { };
+
+// CHECK-LABEL: define void @_ZN6PR98011fEv
+void f() {
+ // CHECK-NOT: call void @llvm.memset.p0i8.i64
+ // CHECK: call void @_ZN6PR98014TestC1Ei
+ // CHECK-NOT: call void @llvm.memset.p0i8.i64
+ // CHECK: call void @_ZN6PR98014TestC1Ev
+ Test partial[3] = { 1 };
+
+ // CHECK-NOT: call void @llvm.memset.p0i8.i64
+ // CHECK: call void @_ZN6PR98014TestC1Ev
+ // CHECK-NOT: call void @_ZN6PR98014TestC1Ev
+ Test empty[3] = {};
+
+ // CHECK: call void @llvm.memset.p0i8.i64
+ // CHECK-NOT: call void @llvm.memset.p0i8.i64
+ // CHECK-CXX98: call void @_ZN6PR98015Test2C1Ev
+ // CHECK-CXX17: call void @_ZN6PR98014TestC1Ev
+ // CHECK-NOT: call void @_ZN6PR98015Test2C1Ev
+ Test2 empty2[3] = {};
+
+ // CHECK: call void @llvm.memset.p0i8.i64
+ // CHECK-NOT: call void @llvm.memset.p0i8.i64
+ // CHECK-CXX98: call void @_ZN6PR98015Test3C1Ev
+ // CHECK-CXX17: call void @_ZN6PR98014TestC2Ev
+ // CHECK-NOT: call void @llvm.memset.p0i8.i64
+ // CHECK-NOT: call void @_ZN6PR98015Test3C1Ev
+ Test3 empty3[3] = {};
+}
+
+}
+
+namespace zeroinit {
+ struct S { int i; };
+
+ // CHECK-LABEL: define i32 @_ZN8zeroinit4testEv()
+ int test() {
+ // CHECK: call void @llvm.memset.p0i8.i64
+ // CHECK: ret i32 0
+ return S().i;
+ }
+
+ struct X0 {
+ X0() { }
+ int x;
+ };
+
+ struct X1 : X0 {
+ int x1;
+ void f();
+ };
+
+ // CHECK-LABEL: define void @_ZN8zeroinit9testX0_X1Ev
+ void testX0_X1() {
+ // CHECK: call void @llvm.memset.p0i8.i64
+ // CHECK-NEXT: call void @_ZN8zeroinit2X1C1Ev
+ // CHECK-NEXT: call void @_ZN8zeroinit2X11fEv
+ X1().f();
+ }
+
+ template<typename>
+ struct X2 : X0 {
+ int x2;
+ void f();
+ };
+
+ template<typename>
+ struct X3 : X2<int> {
+ X3() : X2<int>() { }
+ int i;
+ };
+
+
+ // CHECK-LABEL: define void @_ZN8zeroinit9testX0_X3Ev
+ void testX0_X3() {
+ // CHECK-NOT: call void @llvm.memset
+ // CHECK: call void @_ZN8zeroinit2X3IiEC1Ev
+ // CHECK: call void @_ZN8zeroinit2X2IiE1fEv
+ // CHECK-NEXT: ret void
+ X3<int>().f();
+ }
+
+ // More checks at EOF
+}
+
+namespace PR8726 {
+class C;
+struct S {
+ const C &c1;
+ int i;
+ const C &c2;
+};
+void f(const C& c) {
+ S s = {c, 42, c};
+}
+
+}
+
+// rdar://problem/9355931
+namespace test6 {
+ struct A { A(); A(int); };
+
+ void test() {
+ A arr[10][20] = { 5 };
+ };
+ // CHECK-LABEL: define void @_ZN5test64testEv()
+ // CHECK: [[ARR:%.*]] = alloca [10 x [20 x [[A:%.*]]]],
+
+ // CHECK-NEXT: [[INNER:%.*]] = getelementptr inbounds [10 x [20 x [[A]]]], [10 x [20 x [[A]]]]* [[ARR]], i64 0, i64 0
+ // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [20 x [[A]]], [20 x [[A]]]* [[INNER]], i64 0, i64 0
+ // CHECK-NEXT: call void @_ZN5test61AC1Ei([[A]]* [[T0]], i32 5)
+ // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [[A]], [[A]]* [[T0]], i64 1
+ // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]], [[A]]* [[T0]], i64 20
+ // CHECK-NEXT: br label
+ // CHECK: [[CUR:%.*]] = phi [[A]]* [ [[BEGIN]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ]
+ // CHECK-NEXT: call void @_ZN5test61AC1Ev([[A]]* [[CUR]])
+ // CHECK-NEXT: [[NEXT]] = getelementptr inbounds [[A]], [[A]]* [[CUR]], i64 1
+ // CHECK-NEXT: [[T0:%.*]] = icmp eq [[A]]* [[NEXT]], [[END]]
+ // CHECK-NEXT: br i1
+
+ // CHECK: [[BEGIN:%.*]] = getelementptr inbounds [20 x [[A]]], [20 x [[A]]]* [[INNER]], i64 1
+ // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [20 x [[A]]], [20 x [[A]]]* [[INNER]], i64 10
+ // CHECK-NEXT: br label
+ // CHECK: [[CUR:%.*]] = phi [20 x [[A]]]* [ [[BEGIN]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ]
+
+ // Inner loop.
+ // CHECK-NEXT: [[IBEGIN:%.*]] = getelementptr inbounds [20 x [[A]]], [20 x [[A]]]* [[CUR]], i{{32|64}} 0, i{{32|64}} 0
+ // CHECK-NEXT: [[IEND:%.*]] = getelementptr inbounds [[A]], [[A]]* [[IBEGIN]], i64 20
+ // CHECK-NEXT: br label
+ // CHECK: [[ICUR:%.*]] = phi [[A]]* [ [[IBEGIN]], {{%.*}} ], [ [[INEXT:%.*]], {{%.*}} ]
+ // CHECK-NEXT: call void @_ZN5test61AC1Ev([[A]]* [[ICUR]])
+ // CHECK-NEXT: [[INEXT:%.*]] = getelementptr inbounds [[A]], [[A]]* [[ICUR]], i64 1
+ // CHECK-NEXT: [[T0:%.*]] = icmp eq [[A]]* [[INEXT]], [[IEND]]
+ // CHECK-NEXT: br i1 [[T0]],
+
+ // CHECK: [[NEXT]] = getelementptr inbounds [20 x [[A]]], [20 x [[A]]]* [[CUR]], i64 1
+ // CHECK-NEXT: [[T0:%.*]] = icmp eq [20 x [[A]]]* [[NEXT]], [[END]]
+ // CHECK-NEXT: br i1 [[T0]]
+ // CHECK: ret void
+}
+
+namespace PR11124 {
+ // Make sure C::C doesn't overwrite parts of A while it is zero-initializing B
+ struct A { int a; A(); A(int); };
+ struct B : virtual A { int b; };
+ struct C : B { C(); };
+ C::C() : A(3), B() {}
+ // CHECK-LABEL: define void @_ZN7PR111241CC1Ev
+ // CHECK: call void @llvm.memset.p0i8.i64(i8* align 8 {{.*}}, i8 0, i64 12, i1 false)
+ // CHECK-NEXT: call void @_ZN7PR111241BC2Ev
+ // Make sure C::C doesn't overwrite parts of A while it is zero-initializing B
+
+ struct B2 : virtual A { int B::*b; };
+ struct C2 : B2 { C2(); };
+ C2::C2() : A(3), B2() {}
+ // CHECK-LABEL: define void @_ZN7PR111242C2C1Ev
+ // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %{{.*}}, i8* align 8 {{.*}}, i64 16, i1 false)
+ // CHECK-NEXT: call void @_ZN7PR111242B2C2Ev
+}
+
+// Ensure we produce an i1 here, and don't assert.
+// CHECK-LABEL: define void @_Z9r170806_bv(
+// CHECK: call void @_Z9r170806_ab(i1 zeroext false)
+void r170806_a(bool b = bool());
+void r170806_b() { r170806_a(); }
+
+namespace PR20256 {
+ struct data { int i; };
+
+ template<typename T = int>
+ data g() {
+ data d; // not value-init
+ return d;
+ }
+ template data g();
+ // CHECK-LABEL: define {{.*}} @_ZN7PR202561gIiEENS_4dataEv(
+ // CHECK-NOT: store
+ // CHECK-NOT: memset
+ // CHECK: }
+
+ template<typename ...T>
+ data h(T ...t) {
+ data d(t...); // value-init
+ return d;
+ }
+ template data h();
+ // CHECK-LABEL: define {{.*}} @_ZN7PR202561hIJEEENS_4dataEDpT_(
+ // CHECK: call void @llvm.memset
+ // CHECK: }
+
+
+ template<typename T = int>
+ data j() {
+ data d = {}; // value-init
+ return d;
+ }
+ template data j();
+ // CHECK-LABEL: define {{.*}} @_ZN7PR202561jIiEENS_4dataEv(
+ // CHECK: call void @llvm.memset
+ // CHECK: }
+
+ data f() {
+ data d; // not value-init
+ return d;
+ }
+ // CHECK-LABEL: define {{.*}} @_ZN7PR202561fEv(
+ // CHECK-NOT: store
+ // CHECK-NOT: memset
+ // CHECK: }
+
+ data i() {
+ data d = {}; // value-init
+ return d;
+ }
+ // CHECK-LABEL: define {{.*}} @_ZN7PR202561iEv(
+ // CHECK: call void @llvm.memset
+ // CHECK: }
+}
+
+// CHECK-LABEL: define {{.*}}@_Z20explicitly_defaultedv
+int explicitly_defaulted() {
+ struct A { A() = default; int n; };
+ // CHECK: call void @llvm.memset
+ A a = A();
+ return a.n;
+} // CHECK-LABEL: }
+
+// CHECK-LABEL: define linkonce_odr void @_ZN8zeroinit2X3IiEC2Ev(%"struct.zeroinit::X3"* %this) unnamed_addr
+// CHECK: call void @llvm.memset.p0i8.i64
+// CHECK-NEXT: call void @_ZN8zeroinit2X2IiEC2Ev
+// CHECK-NEXT: ret void
+
+#if __cplusplus >= 201103L
+namespace transparent_init_list {
+ struct optional_assign_base {};
+ struct optional_data_dtor_base { char dummy_[24]; };
+ struct optional : optional_data_dtor_base, optional_assign_base {};
+ optional f(optional a) { return {optional(a)}; }
+}
+#endif
diff --git a/src/llvm-project/clang/test/CodeGenCXX/vararg-conversion-ctor.cpp b/src/llvm-project/clang/test/CodeGenCXX/vararg-conversion-ctor.cpp
new file mode 100644
index 0000000..e496f6d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/vararg-conversion-ctor.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm %s -o %t-64.ll
+// RUN: FileCheck -check-prefix CHECK-LPLL64 --input-file=%t-64.ll %s
+
+extern "C" int printf(...);
+
+struct A {
+ A(...) {
+ printf("A::A(...)\n");
+ }
+};
+
+A a(1.34);
+
+A b = 2.34;
+
+int main()
+{
+ A c[3];
+}
+
+// CHECK-LPLL64: call void (%struct.A*, ...)
+// CHECK-LPLL64: call void (%struct.A*, ...)
+// CHECK-LPLL64: call void (%struct.A*, ...)
diff --git a/src/llvm-project/clang/test/CodeGenCXX/vararg-non-pod-ms-compat.cpp b/src/llvm-project/clang/test/CodeGenCXX/vararg-non-pod-ms-compat.cpp
new file mode 100644
index 0000000..8f41302
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/vararg-non-pod-ms-compat.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -Wno-error=non-pod-varargs -triple i686-pc-win32 -fms-compatibility -emit-llvm -o - %s | FileCheck %s -check-prefix=X86 -check-prefix=CHECK
+// RUN: %clang_cc1 -Wno-error=non-pod-varargs -triple x86_64-pc-win32 -fms-compatibility -emit-llvm -o - %s | FileCheck %s -check-prefix=X64 -check-prefix=CHECK
+
+struct X {
+ X();
+ ~X();
+ int data;
+};
+
+void vararg(...);
+
+void test(X x) {
+ // CHECK-LABEL: define dso_local void @"?test@@YAXUX@@@Z"
+
+ // X86: %[[argmem:[^ ]*]] = alloca inalloca <{ %struct.X }>
+ // X86: call void (<{ %struct.X }>*, ...) bitcast (void (...)* @"?vararg@@YAXZZ" to void (<{ %struct.X }>*, ...)*)(<{ %struct.X }>* inalloca %[[argmem]])
+
+ // X64: alloca %struct.X
+
+ // X64: %[[agg:[^ ]*]] = alloca %struct.X
+ // X64: %[[valptr:[^ ]*]] = getelementptr inbounds %struct.X, %struct.X* %[[agg]], i32 0, i32 0
+ // X64: %[[val:[^ ]*]] = load i32, i32* %[[valptr]]
+ // X64: call void (...) @"?vararg@@YAXZZ"(i32 %[[val]])
+
+ // CHECK-NOT: llvm.trap
+ vararg(x);
+ // CHECK: ret void
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/vararg-non-pod.cpp b/src/llvm-project/clang/test/CodeGenCXX/vararg-non-pod.cpp
new file mode 100644
index 0000000..36891a4
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/vararg-non-pod.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -Wno-error=non-pod-varargs -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
+
+struct X {
+ X();
+ X(const X&);
+ ~X();
+};
+
+void vararg(...);
+
+// CHECK-LABEL: define {{.*}}void @_Z4test1X
+void test(X x) {
+ // CHECK: call void @llvm.trap()
+ vararg(x);
+ // CHECK: ret void
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/varargs.cpp b/src/llvm-project/clang/test/CodeGenCXX/varargs.cpp
new file mode 100644
index 0000000..1f82d60
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/varargs.cpp
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s
+
+// rdar://7309675
+// PR4678
+namespace test0 {
+ // test1 should be compmiled to be a varargs function in the IR even
+ // though there is no way to do a va_begin. Otherwise, the optimizer
+ // will warn about 'dropped arguments' at the call site.
+
+ // CHECK-LABEL: define i32 @_ZN5test05test1Ez(...)
+ int test1(...) {
+ return -1;
+ }
+
+ // CHECK: call i32 (...) @_ZN5test05test1Ez(i32 0)
+ void test() {
+ test1(0);
+ }
+}
+
+namespace test1 {
+ struct A {
+ int x;
+ int y;
+ };
+
+ void foo(...);
+
+ void test() {
+ A x;
+ foo(x);
+ }
+ // CHECK-LABEL: define void @_ZN5test14testEv()
+ // CHECK: [[X:%.*]] = alloca [[A:%.*]], align 4
+ // CHECK-NEXT: [[TMP:%.*]] = alloca [[A]], align 4
+ // CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[TMP]] to i8*
+ // CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[X]] to i8*
+ // CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[T0]], i8* align 4 [[T1]], i64 8, i1 false)
+ // CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[TMP]] to i64*
+ // CHECK-NEXT: [[T1:%.*]] = load i64, i64* [[T0]], align 4
+ // CHECK-NEXT: call void (...) @_ZN5test13fooEz(i64 [[T1]])
+ // CHECK-NEXT: ret void
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/variadic-templates.cpp b/src/llvm-project/clang/test/CodeGenCXX/variadic-templates.cpp
new file mode 100644
index 0000000..4974b65
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/variadic-templates.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
+
+template<typename ...Types>
+int get_num_types(Types...) {
+ return sizeof...(Types);
+}
+
+// CHECK-LABEL: define weak_odr i32 @_Z13get_num_typesIJifdEEiDpT_
+// CHECK: ret i32 3
+template int get_num_types(int, float, double);
+
+// PR10260 - argument packs that expand to nothing
+namespace test1 {
+ template <class... T> void foo() {
+ int values[sizeof...(T)+1] = { T::value... };
+ // CHECK-LABEL: define linkonce_odr void @_ZN5test13fooIJEEEvv()
+ // CHECK: alloca [1 x i32], align 4
+ }
+
+ void test() {
+ foo<>();
+ }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/vector-splat-conversion.cpp b/src/llvm-project/clang/test/CodeGenCXX/vector-splat-conversion.cpp
new file mode 100644
index 0000000..805f9f5
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/vector-splat-conversion.cpp
@@ -0,0 +1,51 @@
+// RUN: %clang_cc1 %s -triple arm64-apple-ios8.1.0 -std=c++11 -emit-llvm -o - | FileCheck %s
+
+typedef __attribute__((__ext_vector_type__(8))) float vector_float8;
+
+typedef vector_float8 float8;
+
+// rdar://20000762
+// CHECK-LABEL: define void @_Z23MandelbrotPolyCalcSIMD8v
+void MandelbrotPolyCalcSIMD8() {
+ constexpr float8 v4 = 4.0; // value to compare against abs(z)^2, to see if bounded
+ float8 vABS;
+ auto vLT = vABS < v4;
+ // CHECK: store <8 x float>
+ // CHECK: [[ZERO:%.*]] = load <8 x float>, <8 x float>* [[VARBS:%.*]]
+ // CHECK: [[CMP:%.*]] = fcmp olt <8 x float> [[ZERO]]
+ // CHECK: [[SEXT:%.*]] = sext <8 x i1> [[CMP]] to <8 x i32>
+ // CHECK: store <8 x i32> [[SEXT]], <8 x i32>* [[VLT:%.*]]
+}
+
+typedef __attribute__((__ext_vector_type__(4))) int int4;
+typedef __attribute__((__ext_vector_type__(4))) float float4;
+typedef __attribute__((__ext_vector_type__(4))) __int128 bigint4;
+
+// CHECK-LABEL: define void @_Z14BoolConversionv
+void BoolConversion() {
+ // CHECK: store <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>
+ int4 intsT = (int4)true;
+ // CHECK: store <4 x i32> zeroinitializer
+ int4 intsF = (int4)false;
+ // CHECK: store <4 x float> <float -1.000000e+00, float -1.000000e+00, float -1.000000e+00, float -1.000000e+00>
+ float4 floatsT = (float4)true;
+ // CHECK: store <4 x float> zeroinitializer
+ float4 floatsF = (float4)false;
+ // CHECK: store <4 x i128> <i128 -1, i128 -1, i128 -1, i128 -1>
+ bigint4 bigintsT = (bigint4)true;
+ // CHECK: store <4 x i128> zeroinitializer
+ bigint4 bigintsF = (bigint4)false;
+
+ // CHECK: store <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>
+ constexpr int4 cIntsT = (int4)true;
+ // CHECK: store <4 x i32> zeroinitializer
+ constexpr int4 cIntsF = (int4)false;
+ // CHECK: store <4 x float> <float -1.000000e+00, float -1.000000e+00, float -1.000000e+00, float -1.000000e+00>
+ constexpr float4 cFloatsT = (float4)true;
+ // CHECK: store <4 x float> zeroinitializer
+ constexpr float4 cFloatsF = (float4)false;
+ // CHECK: store <4 x i128> <i128 -1, i128 -1, i128 -1, i128 -1>
+ constexpr bigint4 cBigintsT = (bigint4)true;
+ // CHECK: store <4 x i128> zeroinitializer
+ constexpr bigint4 cBigintsF = (bigint4)false;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/virt-canonical-decl.cpp b/src/llvm-project/clang/test/CodeGenCXX/virt-canonical-decl.cpp
new file mode 100644
index 0000000..dfc3619
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/virt-canonical-decl.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 %s -emit-llvm-only
+
+class Base {
+public:
+ virtual ~Base();
+};
+
+Base::~Base()
+{
+}
+
+class Foo : public Base {
+public:
+ virtual ~Foo();
+};
+
+Foo::~Foo()
+{
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/virt-dtor-gen.cpp b/src/llvm-project/clang/test/CodeGenCXX/virt-dtor-gen.cpp
new file mode 100644
index 0000000..ba83689
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/virt-dtor-gen.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -o - -triple %itanium_abi_triple -emit-llvm %s | FileCheck %s
+// PR5483
+
+// Make sure we generate all three forms of the destructor when it is virtual.
+class Foo {
+ virtual ~Foo();
+};
+Foo::~Foo() {}
+
+// CHECK-LABEL: define {{.*}}void @_ZN3FooD0Ev(%class.Foo* %this) unnamed_addr
diff --git a/src/llvm-project/clang/test/CodeGenCXX/virt-dtor-key.cpp b/src/llvm-project/clang/test/CodeGenCXX/virt-dtor-key.cpp
new file mode 100644
index 0000000..d1055d4
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/virt-dtor-key.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -triple i386-linux -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple i386-windows-gnu -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-MINGW
+// CHECK: @_ZTI3foo = constant
+// CHECK-MINGW: @_ZTI3foo = linkonce_odr
+class foo {
+ foo();
+ virtual ~foo();
+};
+
+foo::~foo() {
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/virt-template-vtable.cpp b/src/llvm-project/clang/test/CodeGenCXX/virt-template-vtable.cpp
new file mode 100644
index 0000000..66d2332
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/virt-template-vtable.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 %s -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %s
+
+template<class T> class A {
+public:
+ A() {}
+ virtual void a() {}
+};
+class B : A<int> {
+ B();
+};
+B::B() {}
+
+template class A<long>;
+
+extern template class A<short>;
+template class A<short>;
+
+
+// CHECK: @_ZTV1B = linkonce_odr {{(dso_local )?}}unnamed_addr constant
+// CHECK: @_ZTV1AIlE = weak_odr {{(dso_local )?}}unnamed_addr constant
+// CHECK: @_ZTV1AIsE = weak_odr {{(dso_local )?}}unnamed_addr constant
+// CHECK: @_ZTV1AIiE = linkonce_odr {{(dso_local )?}}unnamed_addr constant
+
+template<class T> struct C {
+ virtual void c() {}
+};
+struct D : C<int> {
+ virtual void d();
+};
+void D::d() {}
+
+// CHECK: define {{.*}}@_ZN1CIiE1cEv(
diff --git a/src/llvm-project/clang/test/CodeGenCXX/virt-thunk-reference.cpp b/src/llvm-project/clang/test/CodeGenCXX/virt-thunk-reference.cpp
new file mode 100644
index 0000000..0cd958b
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/virt-thunk-reference.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -emit-llvm-only %s
+
+struct A { int a; virtual void aa(int&); };
+struct B { int b; virtual void bb(int&); };
+struct C : A,B { virtual void aa(int&), bb(int&); };
+void C::aa(int&) {}
+void C::bb(int&) {}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/virtual-base-cast.cpp b/src/llvm-project/clang/test/CodeGenCXX/virtual-base-cast.cpp
new file mode 100644
index 0000000..d3a7999
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/virtual-base-cast.cpp
@@ -0,0 +1,85 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple i686-pc-linux-gnu | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple i686-pc-win32 | FileCheck -check-prefix MSVC %s
+
+struct A { int a; virtual int aa(); };
+struct B { int b; virtual int bb(); };
+struct C : virtual A, virtual B { int c; virtual int aa(); virtual int bb(); };
+struct AA { int a; virtual int aa(); };
+struct BB { int b; virtual int bb(); };
+struct CC : AA, BB { virtual int aa(); virtual int bb(); virtual int cc(); };
+struct D : virtual C, virtual CC { int e; };
+
+D* x;
+
+A* a() { return x; }
+// CHECK: @_Z1av() [[NUW:#[0-9]+]]
+// CHECK: [[VBASEOFFSETPTRA:%[a-zA-Z0-9\.]+]] = getelementptr i8, i8* {{.*}}, i64 -16
+// CHECK: [[CASTVBASEOFFSETPTRA:%[a-zA-Z0-9\.]+]] = bitcast i8* [[VBASEOFFSETPTRA]] to i32*
+// CHECK: load i32, i32* [[CASTVBASEOFFSETPTRA]]
+// CHECK: }
+
+// MSVC: @"?a@@YAPAUA@@XZ"() [[NUW:#[0-9]+]] {
+// MSVC: %[[vbptr_off:.*]] = getelementptr inbounds i8, i8* {{.*}}, i32 0
+// MSVC: %[[vbptr:.*]] = bitcast i8* %[[vbptr_off]] to i32**
+// MSVC: %[[vbtable:.*]] = load i32*, i32** %[[vbptr]]
+// MSVC: %[[entry:.*]] = getelementptr inbounds i32, i32* {{.*}}, i32 1
+// MSVC: %[[offset:.*]] = load i32, i32* %[[entry]]
+// MSVC: add nsw i32 0, %[[offset]]
+// MSVC: }
+
+B* b() { return x; }
+// CHECK: @_Z1bv() [[NUW]]
+// CHECK: [[VBASEOFFSETPTRA:%[a-zA-Z0-9\.]+]] = getelementptr i8, i8* {{.*}}, i64 -20
+// CHECK: [[CASTVBASEOFFSETPTRA:%[a-zA-Z0-9\.]+]] = bitcast i8* [[VBASEOFFSETPTRA]] to i32*
+// CHECK: load i32, i32* [[CASTVBASEOFFSETPTRA]]
+// CHECK: }
+
+// Same as 'a' except we use a different vbtable offset.
+// MSVC: @"?b@@YAPAUB@@XZ"() [[NUW:#[0-9]+]] {
+// MSVC: %[[vbptr_off:.*]] = getelementptr inbounds i8, i8* {{.*}}, i32 0
+// MSVC: %[[vbptr:.*]] = bitcast i8* %[[vbptr_off]] to i32**
+// MSVC: %[[vbtable:.*]] = load i32*, i32** %[[vbptr]]
+// MSVC: %[[entry:.*]] = getelementptr inbounds i32, i32* {{.*}}, i32 2
+// MSVC: %[[offset:.*]] = load i32, i32* %[[entry]]
+// MSVC: add nsw i32 0, %[[offset]]
+// MSVC: }
+
+
+BB* c() { return x; }
+// CHECK: @_Z1cv() [[NUW]]
+// CHECK: [[VBASEOFFSETPTRC:%[a-zA-Z0-9\.]+]] = getelementptr i8, i8* {{.*}}, i64 -24
+// CHECK: [[CASTVBASEOFFSETPTRC:%[a-zA-Z0-9\.]+]] = bitcast i8* [[VBASEOFFSETPTRC]] to i32*
+// CHECK: [[VBASEOFFSETC:%[a-zA-Z0-9\.]+]] = load i32, i32* [[CASTVBASEOFFSETPTRC]]
+// CHECK: add i32 [[VBASEOFFSETC]], 8
+// CHECK: }
+
+// Same as 'a' except we use a different vbtable offset.
+// MSVC: @"?c@@YAPAUBB@@XZ"() [[NUW:#[0-9]+]] {
+// MSVC: %[[vbptr_off:.*]] = getelementptr inbounds i8, i8* {{.*}}, i32 0
+// MSVC: %[[vbptr:.*]] = bitcast i8* %[[vbptr_off]] to i32**
+// MSVC: %[[vbtable:.*]] = load i32*, i32** %[[vbptr]]
+// MSVC: %[[entry:.*]] = getelementptr inbounds i32, i32* {{.*}}, i32 4
+// MSVC: %[[offset:.*]] = load i32, i32* %[[entry]]
+// MSVC: add nsw i32 0, %[[offset]]
+// MSVC: }
+
+// Put the vbptr at a non-zero offset inside a non-virtual base.
+struct E { int e; };
+struct F : E, D { int f; };
+
+F* y;
+
+BB* d() { return y; }
+
+// Same as 'c' except the vbptr offset is 4, changing the initial GEP and the
+// final add.
+// MSVC: @"?d@@YAPAUBB@@XZ"() [[NUW:#[0-9]+]] {
+// MSVC: %[[vbptr_off:.*]] = getelementptr inbounds i8, i8* {{.*}}, i32 4
+// MSVC: %[[vbptr:.*]] = bitcast i8* %[[vbptr_off]] to i32**
+// MSVC: %[[vbtable:.*]] = load i32*, i32** %[[vbptr]]
+// MSVC: %[[entry:.*]] = getelementptr inbounds i32, i32* {{.*}}, i32 4
+// MSVC: %[[offset:.*]] = load i32, i32* %[[entry]]
+// MSVC: add nsw i32 4, %[[offset]]
+// MSVC: }
+
+// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/virtual-base-ctor.cpp b/src/llvm-project/clang/test/CodeGenCXX/virtual-base-ctor.cpp
new file mode 100644
index 0000000..e32296f
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/virtual-base-ctor.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 %s -emit-llvm -triple %itanium_abi_triple -o - -O2 | opt - -S -globalopt -o - | FileCheck %s
+
+struct B;
+extern B x;
+char y;
+typedef __typeof(sizeof(int)) size_t;
+struct A { int a; A() { y = ((size_t)this - (size_t)&x) / sizeof(void*); } };
+struct B : virtual A { void* x; };
+B x;
+
+// CHECK: @y = {{(dso_local )?}}local_unnamed_addr global i8 2
diff --git a/src/llvm-project/clang/test/CodeGenCXX/virtual-base-destructor-call.cpp b/src/llvm-project/clang/test/CodeGenCXX/virtual-base-destructor-call.cpp
new file mode 100644
index 0000000..29f1f5c
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/virtual-base-destructor-call.cpp
@@ -0,0 +1,51 @@
+// RUN: %clang_cc1 %s -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %s
+
+struct basic_ios{~basic_ios(); };
+
+template<typename _CharT> struct basic_istream : virtual public basic_ios {
+ virtual ~basic_istream(){}
+};
+
+template<typename _CharT> struct basic_iostream : public basic_istream<_CharT>
+{
+ virtual ~basic_iostream(){}
+};
+
+basic_iostream<char> res;
+
+int main() {
+}
+
+// basic_iostream's complete dtor calls its base dtor, then its
+// virtual base's dtor.
+// CHECK: define linkonce_odr {{.*}} @_ZN14basic_iostreamIcED1Ev(%struct.basic_iostream* {{.*}}%this) unnamed_addr
+// CHECK: call {{.*}} @_ZN14basic_iostreamIcED2Ev
+// CHECK: call {{.*}} @_ZN9basic_iosD2Ev
+
+// basic_istream's complete dtor calls the base dtor,
+// then its virtual base's base dtor.
+// CHECK: define linkonce_odr {{.*}} @_ZN13basic_istreamIcED1Ev(%struct.basic_istream* {{.*}}%this) unnamed_addr
+// CHECK: call {{.*}} @_ZN13basic_istreamIcED2Ev
+// CHECK: call {{.*}} @_ZN9basic_iosD2Ev
+
+// basic_istream's deleting dtor calls the complete dtor, then
+// operator delete().
+// CHECK: define linkonce_odr {{.*}} @_ZN13basic_istreamIcED0Ev(%struct.basic_istream* {{.*}}%this) unnamed_addr
+// CHECK: call {{.*}} @_ZN13basic_istreamIcED1Ev
+// CHECK: call {{.*}} @_ZdlPv
+
+// basic_iostream's deleting dtor calls its complete dtor, then
+// operator delete().
+// CHECK: define linkonce_odr {{.*}} @_ZN14basic_iostreamIcED0Ev(%struct.basic_iostream* {{.*}}%this) unnamed_addr
+// CHECK: call {{.*}} @_ZN14basic_iostreamIcED1Ev
+// CHECK: call {{.*}} @_ZdlPv
+
+// basic_istream's base dtor is a no-op.
+// CHECK: define linkonce_odr {{.*}} @_ZN13basic_istreamIcED2Ev(%struct.basic_istream* {{.*}}%this, i8** %vtt) unnamed_addr
+// CHECK-NOT: call
+// CHECK: }
+
+// basic_iostream's base dtor calls its non-virtual base dtor.
+// CHECK: define linkonce_odr {{.*}} @_ZN14basic_iostreamIcED2Ev(%struct.basic_iostream* {{.*}}%this, i8** %vtt) unnamed_addr
+// CHECK: call {{.*}} @_ZN13basic_istreamIcED2Ev
+// CHECK: }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/virtual-bases.cpp b/src/llvm-project/clang/test/CodeGenCXX/virtual-bases.cpp
new file mode 100644
index 0000000..259b1c1
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/virtual-bases.cpp
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin10 -mconstructor-aliases | FileCheck %s
+
+struct A {
+ A();
+};
+
+// CHECK: @_ZN1AC1Ev = unnamed_addr alias {{.*}} @_ZN1AC2Ev
+// CHECK-LABEL: define void @_ZN1AC2Ev(%struct.A* %this) unnamed_addr
+A::A() { }
+
+struct B : virtual A {
+ B();
+};
+
+// CHECK-LABEL: define void @_ZN1BC2Ev(%struct.B* %this, i8** %vtt) unnamed_addr
+// CHECK-LABEL: define void @_ZN1BC1Ev(%struct.B* %this) unnamed_addr
+B::B() { }
+
+struct C : virtual A {
+ C(bool);
+};
+
+// CHECK-LABEL: define void @_ZN1CC2Eb(%struct.C* %this, i8** %vtt, i1 zeroext) unnamed_addr
+// CHECK-LABEL: define void @_ZN1CC1Eb(%struct.C* %this, i1 zeroext) unnamed_addr
+C::C(bool) { }
+
+// PR6251
+namespace PR6251 {
+
+// Test that we don't call the A<char> constructor twice.
+
+template<typename T>
+struct A { A(); };
+
+struct B : virtual A<char> { };
+struct C : virtual A<char> { };
+
+struct D : B, C {
+ D();
+};
+
+// CHECK-LABEL: define void @_ZN6PR62511DC1Ev(%"struct.PR6251::D"* %this) unnamed_addr
+// CHECK: call void @_ZN6PR62511AIcEC2Ev
+// CHECK-NOT: call void @_ZN6PR62511AIcEC2Ev
+// CHECK: ret void
+D::D() { }
+
+}
+
+namespace virtualBaseAlignment {
+
+// Check that the store to B::x in the base constructor has an 8-byte alignment.
+
+// CHECK: define linkonce_odr void @_ZN20virtualBaseAlignment1BC1Ev(%[[STRUCT_B:.*]]* %[[THIS:.*]])
+// CHECK: %[[THIS_ADDR:.*]] = alloca %[[STRUCT_B]]*, align 8
+// CHECK: store %[[STRUCT_B]]* %[[THIS]], %[[STRUCT_B]]** %[[THIS_ADDR]], align 8
+// CHECK: %[[THIS1:.*]] = load %[[STRUCT_B]]*, %[[STRUCT_B]]** %[[THIS_ADDR]], align 8
+// CHECK: %[[X:.*]] = getelementptr inbounds %[[STRUCT_B]], %[[STRUCT_B]]* %[[THIS1]], i32 0, i32 2
+// CHECK: store i32 123, i32* %[[X]], align 16
+
+// CHECK: define linkonce_odr void @_ZN20virtualBaseAlignment1BC2Ev(%[[STRUCT_B]]* %[[THIS:.*]], i8** %{{.*}})
+// CHECK: %[[THIS_ADDR:.*]] = alloca %[[STRUCT_B]]*, align 8
+// CHECK: store %[[STRUCT_B]]* %[[THIS]], %[[STRUCT_B]]** %[[THIS_ADDR]], align 8
+// CHECK: %[[THIS1:.*]] = load %[[STRUCT_B]]*, %[[STRUCT_B]]** %[[THIS_ADDR]], align 8
+// CHECK: %[[X:.*]] = getelementptr inbounds %[[STRUCT_B]], %[[STRUCT_B]]* %[[THIS1]], i32 0, i32 2
+// CHECK: store i32 123, i32* %[[X]], align 8
+
+struct A {
+ __attribute__((aligned(16))) double data1;
+};
+
+struct B : public virtual A {
+ B() : x(123) {}
+ double a;
+ int x;
+};
+
+struct C : public virtual B {};
+
+void test() { B b; C c; }
+
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/virtual-destructor-calls.cpp b/src/llvm-project/clang/test/CodeGenCXX/virtual-destructor-calls.cpp
new file mode 100644
index 0000000..10d8236
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/virtual-destructor-calls.cpp
@@ -0,0 +1,59 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin10 -mconstructor-aliases -O1 -disable-llvm-passes | FileCheck %s
+
+struct Member {
+ ~Member();
+};
+
+struct A {
+ virtual ~A();
+};
+
+struct B : A {
+ Member m;
+ virtual ~B();
+};
+
+// Complete dtor: just an alias because there are no virtual bases.
+// CHECK: @_ZN1BD1Ev = unnamed_addr alias {{.*}} @_ZN1BD2Ev
+
+// (aliases from C)
+// CHECK: @_ZN1CD2Ev = unnamed_addr alias {{.*}}, bitcast {{.*}} @_ZN1BD2Ev
+// CHECK: @_ZN1CD1Ev = unnamed_addr alias {{.*}} @_ZN1CD2Ev
+
+// Base dtor: actually calls A's base dtor.
+// CHECK-LABEL: define void @_ZN1BD2Ev(%struct.B* %this) unnamed_addr
+// CHECK: call void @_ZN6MemberD1Ev
+// CHECK: call void @_ZN1AD2Ev
+
+// Deleting dtor: defers to the complete dtor.
+// CHECK-LABEL: define void @_ZN1BD0Ev(%struct.B* %this) unnamed_addr
+// CHECK: call void @_ZN1BD1Ev
+// CHECK: call void @_ZdlPv
+
+B::~B() { }
+
+struct C : B {
+ ~C();
+};
+
+C::~C() { }
+
+// Complete dtor: just an alias (checked above).
+
+// Deleting dtor: defers to the complete dtor.
+// CHECK-LABEL: define void @_ZN1CD0Ev(%struct.C* %this) unnamed_addr
+// CHECK: call void @_ZN1CD1Ev
+// CHECK: call void @_ZdlPv
+
+// Base dtor: just an alias to B's base dtor.
+
+namespace PR12798 {
+ // A qualified call to a base class destructor should not undergo virtual
+ // dispatch. Template instantiation used to lose the qualifier.
+ struct A { virtual ~A(); };
+ template<typename T> void f(T *p) { p->A::~A(); }
+
+ // CHECK: define {{.*}} @_ZN7PR127981fINS_1AEEEvPT_(
+ // CHECK: call void @_ZN7PR127981AD1Ev(
+ template void f(A*);
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/virtual-destructor-synthesis.cpp b/src/llvm-project/clang/test/CodeGenCXX/virtual-destructor-synthesis.cpp
new file mode 100644
index 0000000..5927235
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/virtual-destructor-synthesis.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 %s -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %s
+
+struct box {
+ virtual ~box();
+};
+
+struct pile_box : public box {
+ pile_box(box *);
+};
+
+pile_box::pile_box(box *pp)
+{
+}
+
+// CHECK: call {{.*}}void @_ZdlPv
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/virtual-function-attrs.cpp b/src/llvm-project/clang/test/CodeGenCXX/virtual-function-attrs.cpp
new file mode 100644
index 0000000..873412d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/virtual-function-attrs.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 %s -triple %itanium_abi_triple -std=c++11 -emit-llvm -o - | FileCheck %s
+
+class A {
+ virtual void f();
+ virtual void g();
+ virtual ~A();
+};
+
+void A::f() {}
+
+// CHECK: define {{(dso_local )?}}[[CC:(x86_thiscallcc )?]]void @_ZN1A1fEv({{.*}}) unnamed_addr
+// CHECK: declare {{(dso_local )?}}[[CC]]void @_ZN1A1gEv({{.*}}) unnamed_addr
+// CHECK: declare {{.*}} @_ZN1AD1Ev({{.*}}) unnamed_addr
+// CHECK: declare {{(dso_local )?}}[[CC]]void @_ZN1AD0Ev({{.*}}) unnamed_addr
diff --git a/src/llvm-project/clang/test/CodeGenCXX/virtual-function-calls.cpp b/src/llvm-project/clang/test/CodeGenCXX/virtual-function-calls.cpp
new file mode 100644
index 0000000..61b2fba
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/virtual-function-calls.cpp
@@ -0,0 +1,56 @@
+// RUN: %clang_cc1 %s -triple %itanium_abi_triple -std=c++11 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple %itanium_abi_triple -std=c++11 -emit-llvm -o - -fstrict-vtable-pointers -O1 | FileCheck --check-prefix=CHECK-INVARIANT %s
+
+// PR5021
+namespace PR5021 {
+
+struct A {
+ virtual void f(char);
+};
+
+void f(A *a) {
+ // CHECK: call {{.*}}void %
+ a->f('c');
+}
+
+struct B : virtual A {
+ virtual void f();
+};
+
+void f(B * b) {
+ b->f();
+}
+
+}
+
+namespace Test1 {
+ struct A {
+ virtual ~A();
+ };
+
+ struct B : A {
+ virtual ~B();
+ virtual void f();
+ };
+
+ void f(B *b) {
+ b->f();
+ }
+}
+
+namespace VirtualNoreturn {
+ struct A {
+ [[noreturn]] virtual void f();
+ };
+
+ // CHECK-LABEL: @_ZN15VirtualNoreturn1f
+ // CHECK-INVARIANT-LABEL: define {{(dso_local )?}}void @_ZN15VirtualNoreturn1f
+ void f(A *p) {
+ p->f();
+ // CHECK: call {{.*}}void %{{[^#]*$}}
+ // CHECK-NOT: unreachable
+ // CHECK-INVARIANT: load {{.*}} !invariant.load ![[EMPTY_NODE:[0-9]+]]
+ }
+}
+
+// CHECK-INVARIANT: ![[EMPTY_NODE]] = !{}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/virtual-functions-incomplete-types.cpp b/src/llvm-project/clang/test/CodeGenCXX/virtual-functions-incomplete-types.cpp
new file mode 100644
index 0000000..624c89d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/virtual-functions-incomplete-types.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+struct A;
+
+struct B {
+ virtual void f();
+ virtual A g();
+};
+
+void B::f() { }
+
+// CHECK-LABEL: define i32 @_ZN1D1gEv(%struct.D* %this)
+// CHECK: declare void @_ZN1B1gEv()
+
+struct C;
+
+struct D {
+ virtual void f();
+ virtual C g();
+};
+
+void D::f() { }
+
+struct C {
+ int a;
+};
+
+C D::g() {
+ return C();
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/virtual-implicit-copy-assignment.cpp b/src/llvm-project/clang/test/CodeGenCXX/virtual-implicit-copy-assignment.cpp
new file mode 100644
index 0000000..0310465
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/virtual-implicit-copy-assignment.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
+
+struct D;
+struct B {
+ virtual D& operator = (const D&);
+};
+struct D : B { D(); virtual void a(); };
+void D::a() {}
+
+// CHECK: @_ZTV1D = {{.*}} @_ZN1DaSERKS_
+// CHECK: define linkonce_odr {{.*}} @_ZN1DaSERKS_
diff --git a/src/llvm-project/clang/test/CodeGenCXX/virtual-implicit-move-assignment.cpp b/src/llvm-project/clang/test/CodeGenCXX/virtual-implicit-move-assignment.cpp
new file mode 100644
index 0000000..7c28fb1
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/virtual-implicit-move-assignment.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -std=c++11 -o - %s | FileCheck %s
+
+struct D;
+struct B {
+ virtual D &operator=(D&&) = 0;
+};
+struct D : B { D(); virtual void a(); };
+void D::a() {}
+D d;
+
+// CHECK: @_ZTV1D = {{.*}} @_ZN1DaSEOS_
+// CHECK: define linkonce_odr {{.*}} @_ZN1DaSEOS_
diff --git a/src/llvm-project/clang/test/CodeGenCXX/virtual-inherited-destructor.cpp b/src/llvm-project/clang/test/CodeGenCXX/virtual-inherited-destructor.cpp
new file mode 100644
index 0000000..3ca7b6d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/virtual-inherited-destructor.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 %s -triple %itanium_abi_triple -emit-llvm-only
+
+struct A { virtual ~A(); };
+struct B : A {
+ ~B() { }
+};
+B x;
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/virtual-operator-call.cpp b/src/llvm-project/clang/test/CodeGenCXX/virtual-operator-call.cpp
new file mode 100644
index 0000000..727c8e1
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/virtual-operator-call.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 %s -triple i386-unknown-unknown -emit-llvm -o - | FileCheck %s
+
+struct A {
+ virtual int operator-();
+};
+
+void f(A a, A *ap) {
+ // CHECK: call i32 @_ZN1AngEv(%struct.A* %a)
+ -a;
+
+ // CHECK: call i32 %
+ -*ap;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/virtual-pseudo-destructor-call.cpp b/src/llvm-project/clang/test/CodeGenCXX/virtual-pseudo-destructor-call.cpp
new file mode 100644
index 0000000..b14a34d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/virtual-pseudo-destructor-call.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 %s -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %s
+
+struct A {
+ virtual ~A();
+};
+
+void f(A *a) {
+ // CHECK: define {{.*}} @_Z1fP1A
+ // CHECK: load
+ // CHECK: load
+ // CHECK: [[CALLEE:%[a-zA-Z0-9.]*]] = load
+ // CHECK: call {{.*}} [[CALLEE]](
+ a->~A();
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/visibility-hidden-extern-templates.cpp b/src/llvm-project/clang/test/CodeGenCXX/visibility-hidden-extern-templates.cpp
new file mode 100644
index 0000000..95e8e08
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/visibility-hidden-extern-templates.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -O1 -triple %itanium_abi_triple -emit-llvm -o - -fvisibility hidden %s | FileCheck %s
+
+template<typename T>
+struct X {
+ void f();
+ void g() { }
+};
+
+template<typename T> void X<T>::f() { }
+
+extern template struct X<int>;
+template struct X<int>;
+extern template struct X<char>;
+
+// <rdar://problem/8109763>
+void test_X(X<int> xi, X<char> xc) {
+ // CHECK-LABEL: define weak_odr hidden {{.*}}void @_ZN1XIiE1fEv
+ xi.f();
+ // CHECK-LABEL: define weak_odr hidden {{.*}}void @_ZN1XIiE1gEv
+ xi.g();
+ // CHECK: declare {{.*}}void @_ZN1XIcE1fEv
+ xc.f();
+ // CHECK-LABEL: define available_externally {{.*}}void @_ZN1XIcE1gEv
+ xc.g();
+}
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/visibility-inlines-hidden-staticvar.cpp b/src/llvm-project/clang/test/CodeGenCXX/visibility-inlines-hidden-staticvar.cpp
new file mode 100644
index 0000000..c0fa57d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/visibility-inlines-hidden-staticvar.cpp
@@ -0,0 +1,111 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -std=c++11 -fvisibility-inlines-hidden -emit-llvm -o - %s -O2 -disable-llvm-passes | FileCheck %s
+// RUN: %clang_cc1 -triple i386-unknown-unknown -std=c++11 -emit-llvm -o - %s -O2 -disable-llvm-passes | FileCheck -check-prefixes=CHECK-NO-VIH %s
+// RUN: %clang_cc1 -triple i386-unknown-unknown -std=c++11 -fvisibility hidden -fvisibility-inlines-hidden -emit-llvm -o - %s -O2 -disable-llvm-passes | FileCheck %s --check-prefix=CHECK-VIS-HIDDEN
+// RUN: %clang_cc1 -triple i386-unknown-unknown -std=c++11 -fvisibility protected -fvisibility-inlines-hidden -emit-llvm -o - %s -O2 -disable-llvm-passes | FileCheck %s --check-prefix=CHECK-VIS-PROTECTED
+
+// When a function is hidden due to -fvisibility-inlines-hidden option, static local variables of the function should not be hidden by the option.
+
+// CHECK-DAG: @_ZZ4funcvE3var = internal global i32 0
+// CHECK-DAG: @_ZZ11hidden_funcvE3var = internal global i32 0
+// CHECK-DAG: @_ZZ12default_funcvE3var = internal global i32 0
+// CHECK-DAG: @_ZZ11inline_funcvE3var = linkonce_odr global i32 0, comdat
+// CHECK-DAG: @_ZZ18inline_hidden_funcvE3var = linkonce_odr hidden global i32 0, comdat
+// CHECK-DAG: @_ZZ19inline_default_funcvE3var = linkonce_odr global i32 0, comdat
+// CHECK-DAG: @_ZZN13ExportedClass10inl_methodEvE3var = linkonce_odr global i32 0, comdat, align 4
+// CHECK-DAG: define i32 @_Z4funcv()
+// CHECK-DAG: define hidden i32 @_Z11hidden_funcv()
+// CHECK-DAG: define i32 @_Z12default_funcv()
+// CHECK-DAG: define linkonce_odr hidden i32 @_Z11inline_funcv()
+// CHECK-DAG: define linkonce_odr hidden i32 @_Z18inline_hidden_funcv()
+// CHECK-DAG: define linkonce_odr i32 @_Z19inline_default_funcv()
+// CHECK-DAG: define linkonce_odr hidden i32 @_ZN13ExportedClass10inl_methodEv({{.*}})
+// CHECK-DAG: define i32 @_ZN13ExportedClass10ext_methodEv({{.*}})
+
+// CHECK-NO-VIH-DAG: @_ZZ4funcvE3var = internal global i32 0
+// CHECK-NO-VIH-DAG: @_ZZ11hidden_funcvE3var = internal global i32 0
+// CHECK-NO-VIH-DAG: @_ZZ12default_funcvE3var = internal global i32 0
+// CHECK-NO-VIH-DAG: @_ZZ11inline_funcvE3var = linkonce_odr global i32 0, comdat
+// CHECK-NO-VIH-DAG: @_ZZ18inline_hidden_funcvE3var = linkonce_odr hidden global i32 0, comdat
+// CHECK-NO-VIH-DAG: @_ZZ19inline_default_funcvE3var = linkonce_odr global i32 0, comdat
+// CHECK-NO-VIH-DAG: @_ZZN13ExportedClass10inl_methodEvE3var = linkonce_odr global i32 0, comdat, align 4
+// CHECK-NO-VIH-DAG: define i32 @_Z4funcv()
+// CHECK-NO-VIH-DAG: define hidden i32 @_Z11hidden_funcv()
+// CHECK-NO-VIH-DAG: define i32 @_Z12default_funcv()
+// CHECK-NO-VIH-DAG: define linkonce_odr i32 @_Z11inline_funcv()
+// CHECK-NO-VIH-DAG: define linkonce_odr hidden i32 @_Z18inline_hidden_funcv()
+// CHECK-NO-VIH-DAG: define linkonce_odr i32 @_Z19inline_default_funcv()
+// CHECK-NO-VIH-DAG: define linkonce_odr i32 @_ZN13ExportedClass10inl_methodEv({{.*}})
+// CHECK-NO-VIH-DAG: define i32 @_ZN13ExportedClass10ext_methodEv({{.*}})
+
+// CHECK-VIS-HIDDEN-DAG: @_ZZ4funcvE3var = internal global i32 0
+// CHECK-VIS-HIDDEN-DAG: @_ZZ11hidden_funcvE3var = internal global i32 0
+// CHECK-VIS-HIDDEN-DAG: @_ZZ12default_funcvE3var = internal global i32 0
+// CHECK-VIS-HIDDEN-DAG: @_ZZ11inline_funcvE3var = linkonce_odr hidden global i32 0, comdat
+// CHECK-VIS-HIDDEN-DAG: @_ZZ18inline_hidden_funcvE3var = linkonce_odr hidden global i32 0, comdat
+// CHECK-VIS-HIDDEN-DAG: @_ZZ19inline_default_funcvE3var = linkonce_odr global i32 0, comdat
+// CHECK-VIS-HIDDEN-DAG: @_ZZN13ExportedClass10inl_methodEvE3var = linkonce_odr global i32 0, comdat, align 4
+// CHECK-VIS-HIDDEN-DAG: define hidden i32 @_Z4funcv()
+// CHECK-VIS-HIDDEN-DAG: define hidden i32 @_Z11hidden_funcv()
+// CHECK-VIS-HIDDEN-DAG: define i32 @_Z12default_funcv()
+// CHECK-VIS-HIDDEN-DAG: define linkonce_odr hidden i32 @_Z11inline_funcv()
+// CHECK-VIS-HIDDEN-DAG: define linkonce_odr hidden i32 @_Z18inline_hidden_funcv()
+// CHECK-VIS-HIDDEN-DAG: define linkonce_odr i32 @_Z19inline_default_funcv()
+// CHECK-VIS-HIDDEN-DAG: define linkonce_odr hidden i32 @_ZN13ExportedClass10inl_methodEv({{.*}})
+// CHECK-VIS-HIDDEN-DAG: define i32 @_ZN13ExportedClass10ext_methodEv({{.*}})
+
+// CHECK-VIS-PROTECTED-DAG: @_ZZ4funcvE3var = internal global i32 0
+// CHECK-VIS-PROTECTED-DAG: @_ZZ11hidden_funcvE3var = internal global i32 0
+// CHECK-VIS-PROTECTED-DAG: @_ZZ12default_funcvE3var = internal global i32 0
+// CHECK-VIS-PROTECTED-DAG: @_ZZ11inline_funcvE3var = linkonce_odr protected global i32 0, comdat
+// CHECK-VIS-PROTECTED-DAG: @_ZZ18inline_hidden_funcvE3var = linkonce_odr hidden global i32 0, comdat
+// CHECK-VIS-PROTECTED-DAG: @_ZZ19inline_default_funcvE3var = linkonce_odr global i32 0, comdat
+// CHECK-VIS-PROTECTED-DAG: @_ZZN13ExportedClass10inl_methodEvE3var = linkonce_odr global i32 0, comdat, align 4
+// CHECK-VIS-PROTECTED-DAG: define protected i32 @_Z4funcv()
+// CHECK-VIS-PROTECTED-DAG: define hidden i32 @_Z11hidden_funcv()
+// CHECK-VIS-PROTECTED-DAG: define i32 @_Z12default_funcv()
+// CHECK-VIS-PROTECTED-DAG: define linkonce_odr hidden i32 @_Z11inline_funcv()
+// CHECK-VIS-PROTECTED-DAG: define linkonce_odr hidden i32 @_Z18inline_hidden_funcv()
+// CHECK-VIS-PROTECTED-DAG: define linkonce_odr i32 @_Z19inline_default_funcv()
+// CHECK-VIS-PROTECTED-DAG: define linkonce_odr hidden i32 @_ZN13ExportedClass10inl_methodEv({{.*}})
+// CHECK-VIS-PROTECTED-DAG: define i32 @_ZN13ExportedClass10ext_methodEv({{.*}})
+
+int func(void) {
+ static int var = 0;
+ return var++;
+}
+inline int inline_func(void) {
+ static int var = 0;
+ return var++;
+}
+int __attribute__((visibility("hidden"))) hidden_func(void) {
+ static int var = 0;
+ return var++;
+}
+inline int __attribute__((visibility("hidden"))) inline_hidden_func(void) {
+ static int var = 0;
+ return var++;
+}
+int __attribute__((visibility("default"))) default_func(void) {
+ static int var = 0;
+ return var++;
+}
+inline int __attribute__((visibility("default"))) inline_default_func(void) {
+ static int var = 0;
+ return var++;
+}
+struct __attribute__((visibility("default"))) ExportedClass {
+ int inl_method() {
+ static int var = 0;
+ return var++;
+ }
+ int ext_method();
+};
+int ExportedClass::ext_method() { return inl_method(); }
+void bar(void) {
+ func();
+ inline_func();
+ hidden_func();
+ inline_hidden_func();
+ default_func();
+ inline_default_func();
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/visibility-inlines-hidden.cpp b/src/llvm-project/clang/test/CodeGenCXX/visibility-inlines-hidden.cpp
new file mode 100644
index 0000000..20e4a1f
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/visibility-inlines-hidden.cpp
@@ -0,0 +1,177 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -std=c++11 -fvisibility-inlines-hidden -emit-llvm -o - %s -O2 -disable-llvm-passes | 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() { }
+ void f3();
+ static void f5() { }
+ virtual void f6() { }
+};
+
+inline void X0::f3() { }
+
+template<typename T>
+struct X1 {
+ void __attribute__((visibility("default"))) f1() { }
+ void f2() { }
+ void f3();
+ void f4();
+ static void f5() { }
+ virtual void f6() { }
+};
+
+template<typename T>
+inline void X1<T>::f3() { }
+
+template<>
+inline void X1<int>::f4() { }
+
+struct __attribute__((visibility("default"))) X2 {
+ void f2() { }
+};
+
+extern template struct X1<float>;
+
+void use(X0 *x0, X1<int> *x1, X2 *x2, X1<float> *x3) {
+ // CHECK-LABEL: define linkonce_odr void @_ZN2X02f1Ev
+ x0->f1();
+ // CHECK-LABEL: define linkonce_odr hidden void @_ZN2X02f2Ev
+ x0->f2();
+ // CHECK-LABEL: define linkonce_odr hidden void @_ZN2X02f3Ev
+ x0->f3();
+ // CHECK-LABEL: define linkonce_odr hidden void @_ZN2X02f5Ev
+ X0::f5();
+ // CHECK-LABEL: define linkonce_odr hidden void @_ZN2X02f6Ev
+ x0->X0::f6();
+ // CHECK-LABEL: define linkonce_odr void @_ZN2X1IiE2f1Ev
+ x1->f1();
+ // CHECK-LABEL: define linkonce_odr hidden void @_ZN2X1IiE2f2Ev
+ x1->f2();
+ // CHECK-LABEL: define linkonce_odr hidden void @_ZN2X1IiE2f3Ev
+ x1->f3();
+ // CHECK-LABEL: define linkonce_odr hidden void @_ZN2X1IiE2f4Ev
+ x1->f4();
+ // CHECK-LABEL: define linkonce_odr hidden void @_ZN2X1IiE2f5Ev
+ X1<int>::f5();
+ // CHECK-LABEL: define linkonce_odr hidden void @_ZN2X1IiE2f6Ev
+ x1->X1::f6();
+ // CHECK-LABEL: define linkonce_odr hidden void @_ZN2X22f2Ev
+ x2->f2();
+ // CHECK-LABEL: 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 {{.*}} @_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-LABEL: define available_externally void @_ZN5test22ns3fooINS_1BINS_1AEEEEEvv()
+}
+
+namespace PR11642 {
+ template <typename T>
+ class Foo {
+ public:
+ T foo(T x) { return x; }
+ };
+ extern template class Foo<int>;
+ template class Foo<int>;
+ // CHECK-LABEL: define weak_odr i32 @_ZN7PR116423FooIiE3fooEi
+}
+
+// Test that clang implements the new gcc behaviour for inline functions.
+// GCC PR30066.
+namespace test3 {
+ inline void foo(void) {
+ }
+ template<typename T>
+ inline void zed() {
+ }
+ template void zed<float>();
+ void bar(void) {
+ foo();
+ zed<int>();
+ }
+ // CHECK-LABEL: define weak_odr void @_ZN5test33zedIfEEvv
+ // CHECK-LABEL: define linkonce_odr hidden void @_ZN5test33fooEv
+ // CHECK-LABEL: define linkonce_odr hidden void @_ZN5test33zedIiEEvv
+}
+
+namespace test4 {
+ extern inline __attribute__ ((__gnu_inline__))
+ void foo() {}
+ void bar() {
+ foo();
+ }
+ // CHECK-LABEL: define available_externally void @_ZN5test43fooE
+}
+
+namespace test5 {
+ // just don't crash.
+ template <int> inline void Op();
+ class UnaryInstruction {
+ UnaryInstruction() {
+ Op<0>();
+ }
+ };
+ template <int Idx_nocapture> void Op() {
+ }
+}
+
+namespace test6 {
+ // just don't crash.
+ template <typename T>
+ void f(T x) {
+ }
+ struct C {
+ static void g() {
+ f([](){});
+ }
+ };
+ void g() {
+ C::g();
+ }
+}
+
+namespace PR34811 {
+ template <typename T> void tf() {}
+
+ // CHECK-LABEL: define linkonce_odr hidden i8* @_ZN7PR348111fEv(
+ inline void *f() {
+ auto l = []() {};
+ // CHECK-LABEL: define linkonce_odr hidden void @_ZN7PR348112tfIZNS_1fEvEUlvE_EEvv(
+ return (void *)&tf<decltype(l)>;
+ }
+
+ void *p = (void *)f;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/visibility-ms-compat.cpp b/src/llvm-project/clang/test/CodeGenCXX/visibility-ms-compat.cpp
new file mode 100644
index 0000000..963b2a4
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/visibility-ms-compat.cpp
@@ -0,0 +1,112 @@
+// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-apple-darwin10 -fvisibility hidden -ftype-visibility default -emit-llvm -o %t
+// RUN: FileCheck %s < %t
+// RUN: FileCheck -check-prefix=CHECK-GLOBAL %s < %t
+
+// The two visibility options above are how we translate
+// -fvisibility-ms-compat in the driver.
+
+// rdar://13079314
+
+#define HIDDEN __attribute__((visibility("hidden")))
+#define PROTECTED __attribute__((visibility("protected")))
+#define DEFAULT __attribute__((visibility("default")))
+
+namespace std {
+ class type_info;
+};
+
+namespace test0 {
+ struct A {
+ static void foo();
+ static void bar();
+ };
+
+ void A::foo() { bar(); }
+ // CHECK-LABEL: define hidden void @_ZN5test01A3fooEv()
+ // CHECK: declare void @_ZN5test01A3barEv()
+
+ const std::type_info &ti = typeid(A);
+ // CHECK-GLOBAL: @_ZTSN5test01AE = linkonce_odr constant
+ // CHECK-GLOBAL: @_ZTIN5test01AE = linkonce_odr constant
+ // CHECK-GLOBAL: @_ZN5test02tiE = hidden constant
+}
+
+namespace test1 {
+ struct HIDDEN A {
+ static void foo();
+ static void bar();
+ };
+
+ void A::foo() { bar(); }
+ // CHECK-LABEL: define hidden void @_ZN5test11A3fooEv()
+ // CHECK: declare hidden void @_ZN5test11A3barEv()
+
+ const std::type_info &ti = typeid(A);
+ // CHECK-GLOBAL: @_ZTSN5test11AE = linkonce_odr hidden constant
+ // CHECK-GLOBAL: @_ZTIN5test11AE = linkonce_odr hidden constant
+ // CHECK-GLOBAL: @_ZN5test12tiE = hidden constant
+}
+
+namespace test2 {
+ struct DEFAULT A {
+ static void foo();
+ static void bar();
+ };
+
+ void A::foo() { bar(); }
+ // CHECK-LABEL: define void @_ZN5test21A3fooEv()
+ // CHECK: declare void @_ZN5test21A3barEv()
+
+ const std::type_info &ti = typeid(A);
+ // CHECK-GLOBAL: @_ZTSN5test21AE = linkonce_odr constant
+ // CHECK-GLOBAL: @_ZTIN5test21AE = linkonce_odr constant
+ // CHECK-GLOBAL: @_ZN5test22tiE = hidden constant
+}
+
+namespace test3 {
+ struct A { int x; };
+ template <class T> struct B {
+ static void foo() { bar(); }
+ static void bar();
+ };
+
+ template void B<A>::foo();
+ // CHECK-LABEL: define weak_odr hidden void @_ZN5test31BINS_1AEE3fooEv()
+ // CHECK: declare void @_ZN5test31BINS_1AEE3barEv()
+
+ const std::type_info &ti = typeid(B<A>);
+ // CHECK-GLOBAL: @_ZTSN5test31BINS_1AEEE = linkonce_odr constant
+ // CHECK-GLOBAL: @_ZTIN5test31BINS_1AEEE = linkonce_odr constant
+}
+
+namespace test4 {
+ struct A { int x; };
+ template <class T> struct DEFAULT B {
+ static void foo() { bar(); }
+ static void bar();
+ };
+
+ template void B<A>::foo();
+ // CHECK-LABEL: define weak_odr void @_ZN5test41BINS_1AEE3fooEv()
+ // CHECK: declare void @_ZN5test41BINS_1AEE3barEv()
+
+ const std::type_info &ti = typeid(B<A>);
+ // CHECK-GLOBAL: @_ZTSN5test41BINS_1AEEE = linkonce_odr constant
+ // CHECK-GLOBAL: @_ZTIN5test41BINS_1AEEE = linkonce_odr constant
+}
+
+namespace test5 {
+ struct A { int x; };
+ template <class T> struct HIDDEN B {
+ static void foo() { bar(); }
+ static void bar();
+ };
+
+ template void B<A>::foo();
+ // CHECK-LABEL: define weak_odr hidden void @_ZN5test51BINS_1AEE3fooEv()
+ // CHECK: declare hidden void @_ZN5test51BINS_1AEE3barEv()
+
+ const std::type_info &ti = typeid(B<A>);
+ // CHECK-GLOBAL: @_ZTSN5test51BINS_1AEEE = linkonce_odr hidden constant
+ // CHECK-GLOBAL: @_ZTIN5test51BINS_1AEEE = linkonce_odr hidden constant
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/visibility-pr36810.cpp b/src/llvm-project/clang/test/CodeGenCXX/visibility-pr36810.cpp
new file mode 100644
index 0000000..5df1df6
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/visibility-pr36810.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macosx -std=c++11 -fvisibility hidden -emit-llvm -o - %s -O2 -disable-llvm-passes | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-macosx -DUNDEF_G -std=c++11 -fvisibility hidden -emit-llvm -o - %s -O2 -disable-llvm-passes | FileCheck %s
+
+namespace std {
+template <class>
+class __attribute__((__type_visibility__("default"))) shared_ptr {
+ template <class> friend class shared_ptr;
+};
+}
+struct dict;
+#ifndef UNDEF_G
+std::shared_ptr<dict> g;
+#endif
+class __attribute__((visibility("default"))) Bar;
+template <class = std::shared_ptr<Bar>>
+class __attribute__((visibility("default"))) i {
+ std::shared_ptr<int> foo() const;
+};
+
+// CHECK: define void @_ZNK1iISt10shared_ptrI3BarEE3fooEv
+template <> std::shared_ptr<int> i<>::foo() const {
+ return std::shared_ptr<int>();
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/visibility.cpp b/src/llvm-project/clang/test/CodeGenCXX/visibility.cpp
new file mode 100644
index 0000000..aff6554
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/visibility.cpp
@@ -0,0 +1,1319 @@
+// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-apple-darwin10 -fvisibility hidden -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-HIDDEN
+// For clang, "internal" is just an alias for "hidden". We could use it for some
+// optimization purposes on 32-bit x86, but it's not worth it.
+// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-apple-darwin10 -fvisibility internal -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-HIDDEN
+
+#define HIDDEN __attribute__((visibility("hidden")))
+#define PROTECTED __attribute__((visibility("protected")))
+#define DEFAULT __attribute__((visibility("default")))
+
+namespace test30 {
+ // When H is hidden, it should make X hidden, even if the template argument
+ // is not.
+ struct H {
+ };
+ template<H *T>
+ struct X {
+ };
+ H DEFAULT a;
+ X<&a> b;
+ // CHECK: _ZN6test301bE = global
+ // CHECK-HIDDEN: _ZN6test301bE = hidden global
+}
+
+namespace test25 {
+ template<typename T>
+ struct X {
+ template<typename U>
+ struct definition {
+ };
+ };
+
+ class DEFAULT A { };
+
+ X<int>::definition<A> a;
+ // CHECK: @_ZN6test251aE = global
+ // CHECK-HIDDEN: @_ZN6test251aE = hidden global
+}
+
+namespace test28 {
+ class DEFAULT foo {
+ };
+ foo myvec;
+ // CHECK: @_ZN6test285myvecE = global
+ // CHECK-HIDDEN: @_ZN6test285myvecE = hidden global
+}
+
+namespace test29 {
+#pragma GCC visibility push(hidden)
+ struct RECT {
+ int top;
+ };
+ DEFAULT extern RECT data_rect;
+ RECT data_rect = { -1};
+#pragma GCC visibility pop
+ // CHECK: @_ZN6test299data_rectE = global
+ // CHECK-HIDDEN: @_ZN6test299data_rectE = global
+}
+
+namespace test40 {
+ template<typename T>
+ struct foo {
+ DEFAULT static int bar;
+ };
+ template<typename T>
+ int foo<T>::bar;
+ template struct foo<int>;
+ // CHECK: _ZN6test403fooIiE3barE = weak_odr global
+ // CHECK-HIDDEN: _ZN6test403fooIiE3barE = weak_odr global
+}
+
+namespace test41 {
+ // Unlike gcc we propagate the information that foo not only is hidden, but
+ // has been explicitly marked as so. This lets us produce a hidden undefined
+ // reference to bar.
+ struct HIDDEN foo {};
+ extern foo bar;
+ foo *zed() {
+ return &bar;
+ }
+ // CHECK: @_ZN6test413barE = external hidden global
+ // CHECK-HIDDEN: @_ZN6test413barE = external hidden global
+}
+
+namespace test48 {
+ // Test that we use the visibility of struct foo when instantiating the
+ // template. Note that is a case where we disagree with gcc, it produces
+ // a default symbol.
+ struct HIDDEN foo {
+ };
+ DEFAULT foo x;
+
+ struct bar {
+ template<foo *z>
+ struct zed {
+ };
+ };
+
+ bar::zed<&x> y;
+ // CHECK: _ZN6test481yE = hidden global
+ // CHECK-HIDDEN: _ZN6test481yE = hidden global
+}
+
+// CHECK: @_ZN5Test425VariableInHiddenNamespaceE = hidden global i32 10
+// 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]
+
+namespace test27 {
+ template<typename T>
+ class C {
+ class DEFAULT D {
+ void f();
+ };
+ };
+
+ template<>
+ class C<int>::D {
+ virtual void g();
+ };
+
+ void C<int>::D::g() {
+ }
+ // CHECK: _ZTVN6test271CIiE1DE = unnamed_addr constant
+ // CHECK-HIDDEN: _ZTVN6test271CIiE1DE = unnamed_addr constant
+}
+
+// CHECK: @_ZTVN5Test63fooE = linkonce_odr hidden unnamed_addr constant
+
+// CHECK-HIDDEN: @_ZTVN6Test161AIcEE = external unnamed_addr constant
+// CHECK-HIDDEN: @_ZTTN6Test161AIcEE = external unnamed_addr constant
+
+// CHECK: @_ZZN6test681fC1EvE4test = linkonce_odr global
+// CHECK-HIDDEN: @_ZZN6test681fC1EvE4test = linkonce_odr hidden global
+
+// CHECK: @_ZGVZN6test681fC1EvE4test = linkonce_odr global
+// CHECK-HIDDEN: @_ZGVZN6test681fC1EvE4test = linkonce_odr hidden global
+
+// CHECK: @_ZZN6Test193fooIiEEvvE1a = linkonce_odr global
+// CHECK-HIDDEN: @_ZZN6Test193fooIiEEvvE1a = linkonce_odr hidden global
+
+// CHECK: @_ZGVZN6Test193fooIiEEvvE1a = linkonce_odr global i64
+// CHECK-HIDDEN: @_ZGVZN6Test193fooIiEEvvE1a = linkonce_odr hidden global i64
+
+namespace Test1 {
+ // CHECK-LABEL: define hidden void @_ZN5Test11fEv
+ void HIDDEN f() { }
+
+}
+
+namespace Test2 {
+ struct HIDDEN A {
+ void f();
+ };
+
+ // A::f is a member function of a hidden class.
+ // CHECK-LABEL: define hidden void @_ZN5Test21A1fEv
+ void A::f() { }
+}
+
+namespace Test3 {
+ struct HIDDEN A {
+ struct B {
+ void f();
+ };
+ };
+
+ // B is a nested class where its parent class is hidden.
+ // CHECK-LABEL: define hidden void @_ZN5Test31A1B1fEv
+ void A::B::f() { }
+}
+
+namespace Test4 HIDDEN {
+ int VariableInHiddenNamespace = 10;
+
+ // Test4::g is in a hidden namespace.
+ // CHECK-LABEL: define hidden void @_ZN5Test41gEv
+ void g() { }
+
+ struct DEFAULT A {
+ void f();
+ };
+
+ // A has default visibility.
+ // CHECK-LABEL: define void @_ZN5Test41A1fEv
+ void A::f() { }
+}
+
+namespace Test5 {
+
+ namespace NS HIDDEN {
+ // f is in NS which is hidden.
+ // CHECK-LABEL: define hidden void @_ZN5Test52NS1fEv()
+ void f() { }
+ }
+
+ namespace NS {
+ // g is in NS, but this NS decl is not hidden.
+ // CHECK-LABEL: define void @_ZN5Test52NS1gEv
+ void g() { }
+ }
+}
+
+// <rdar://problem/8091955>
+namespace Test6 {
+ struct HIDDEN foo {
+ foo() { }
+ void bonk();
+ virtual void bar() = 0;
+
+ virtual void zonk() {}
+ };
+
+ struct barc : public foo {
+ barc();
+ virtual void bar();
+ };
+
+ 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-LABEL: define linkonce_odr hidden void @_ZN5Test74ArefIL_ZNS_1aEEE3fooEv()
+ void test() {
+ Aref<a>::foo();
+ }
+}
+
+namespace Test8 {
+ void foo();
+ void bar() {}
+ // CHECK-HIDDEN-LABEL: 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-LABEL: define void @test9_fun(
+ // CHECK-HIDDEN-LABEL: define void @test9_fun(
+
+ void test() {
+ A a = test9_var;
+ test9_fun(&a);
+ }
+}
+
+// PR8478
+namespace Test10 {
+ struct A;
+
+ class DEFAULT B {
+ void foo(A*);
+ };
+
+ // CHECK-LABEL: define void @_ZN6Test101B3fooEPNS_1AE(
+ // CHECK-HIDDEN-LABEL: 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-LABEL: define linkonce_odr void @_ZN6Test111A3fooEv(
+ // CHECK-LABEL: define linkonce_odr void @_ZN6Test111A3barEv(
+ // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6Test111A3fooEv(
+ // CHECK-HIDDEN-LABEL: 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-LABEL: 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-LABEL: 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-LABEL: define linkonce_odr hidden void @_ZN6Test201BINS_1AILj2EEEE5test4Ev()
+ void test4() {
+ B<A<2> >::test4();
+ }
+
+ // CHECK: declare hidden void @_ZN6Test201BINS_1AILj2EEEE5test5Ev()
+ void test5() {
+ B<A<2> >::test5();
+ }
+}
+
+// PR9371
+namespace test21 {
+ enum En { en };
+ template<En> struct A {
+ DEFAULT void foo() {}
+ };
+
+ // CHECK-LABEL: define weak_odr void @_ZN6test211AILNS_2EnE0EE3fooEv(
+ template void A<en>::foo();
+}
+
+// rdar://problem/9616154
+// Visibility on explicit specializations should take precedence.
+namespace test22 {
+ class A1 {};
+ class A2 {};
+
+ template <class T> struct B {};
+ template <> struct DEFAULT B<A1> {
+ static void foo();
+ static void bar() {}
+ };
+ template <> struct B<A2> {
+ static void foo();
+ static void bar() {}
+ };
+
+ void test() {
+ B<A1>::foo();
+ B<A1>::bar();
+ B<A2>::foo();
+ B<A2>::bar();
+ }
+ // CHECK: declare void @_ZN6test221BINS_2A1EE3fooEv()
+ // CHECK-LABEL: define linkonce_odr void @_ZN6test221BINS_2A1EE3barEv()
+ // CHECK: declare void @_ZN6test221BINS_2A2EE3fooEv()
+ // CHECK-LABEL: define linkonce_odr void @_ZN6test221BINS_2A2EE3barEv()
+ // CHECK-HIDDEN: declare void @_ZN6test221BINS_2A1EE3fooEv()
+ // CHECK-HIDDEN-LABEL: define linkonce_odr void @_ZN6test221BINS_2A1EE3barEv()
+ // CHECK-HIDDEN: declare void @_ZN6test221BINS_2A2EE3fooEv()
+ // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test221BINS_2A2EE3barEv()
+}
+
+namespace PR10113 {
+ namespace foo DEFAULT {
+ template<typename T>
+ class bar {
+ void zed() {}
+ };
+ }
+ template class foo::bar<char>;
+ // CHECK-LABEL: define weak_odr void @_ZN7PR101133foo3barIcE3zedEv
+ // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN7PR101133foo3barIcE3zedEv
+
+ struct zed {
+ };
+ template class foo::bar<zed>;
+ // CHECK-LABEL: define weak_odr void @_ZN7PR101133foo3barINS_3zedEE3zedEv
+ // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN7PR101133foo3barINS_3zedEE3zedEv
+}
+
+namespace PR11690 {
+ template<class T> struct Class {
+ void size() const {
+ }
+ };
+ template class DEFAULT Class<char>;
+ // CHECK-LABEL: define weak_odr void @_ZNK7PR116905ClassIcE4sizeEv
+ // CHECK-HIDDEN-LABEL: define weak_odr void @_ZNK7PR116905ClassIcE4sizeEv
+
+ template<class T> void Method() {}
+ template DEFAULT void Method<char>();
+ // CHECK-LABEL: define weak_odr void @_ZN7PR116906MethodIcEEvv
+ // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN7PR116906MethodIcEEvv
+}
+
+namespace PR11690_2 {
+ namespace foo DEFAULT {
+ class bar;
+ template<typename T1, typename T2 = bar>
+ class zed {
+ void bar() {
+ }
+ };
+ }
+ struct baz {
+ };
+ template class foo::zed<baz>;
+ // CHECK-LABEL: define weak_odr void @_ZN9PR11690_23foo3zedINS_3bazENS0_3barEE3barEv
+ // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN9PR11690_23foo3zedINS_3bazENS0_3barEE3barEv
+}
+
+namespace test23 {
+ // Having a template argument that is explicitly visible should not make
+ // the template instantiation visible.
+ template <typename T>
+ struct X {
+ static void f() {
+ }
+ };
+
+ class DEFAULT A;
+
+ void g() {
+ X<A> y;
+ y.f();
+ }
+ // CHECK-LABEL: define linkonce_odr void @_ZN6test231XINS_1AEE1fEv
+ // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test231XINS_1AEE1fEv
+}
+
+namespace PR12001 {
+ template <typename P1>
+ void Bind(const P1& p1) {
+ }
+
+ class DEFAULT Version { };
+
+ void f() {
+ Bind(Version());
+ }
+ // CHECK-LABEL: define linkonce_odr void @_ZN7PR120014BindINS_7VersionEEEvRKT_
+ // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN7PR120014BindINS_7VersionEEEvRKT_
+}
+
+namespace test24 {
+ class DEFAULT A { };
+
+ struct S {
+ template <typename T>
+ void mem() {}
+ };
+
+ void test() {
+ S s;
+ s.mem<A>();
+ }
+ // CHECK-LABEL: define linkonce_odr void @_ZN6test241S3memINS_1AEEEvv
+ // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test241S3memINS_1AEEEvv
+}
+
+namespace test26 {
+ template<typename T>
+ class C {
+ DEFAULT void f();
+ };
+
+ template<>
+ void C<int>::f() { }
+
+ // CHECK-LABEL: define void @_ZN6test261CIiE1fEv
+ // CHECK-HIDDEN-LABEL: define void @_ZN6test261CIiE1fEv
+}
+
+namespace test31 {
+ struct A {
+ struct HIDDEN B {
+ static void DEFAULT baz();
+ };
+ };
+ void f() {
+ A::B::baz();
+ }
+ // CHECK: declare void @_ZN6test311A1B3bazEv()
+ // CHECK-HIDDEN: declare void @_ZN6test311A1B3bazEv()
+}
+
+namespace test32 {
+ struct HIDDEN A {
+ struct DEFAULT B {
+ void DEFAULT baz();
+ };
+ };
+ void A::B::baz() {
+ }
+ // CHECK-LABEL: define void @_ZN6test321A1B3bazEv
+ // CHECK-HIDDEN-LABEL: define void @_ZN6test321A1B3bazEv
+}
+
+namespace test33 {
+ template<typename T>
+ class foo {
+ void bar() {}
+ };
+ struct HIDDEN zed {
+ };
+ template class DEFAULT foo<zed>;
+ // CHECK-LABEL: define weak_odr void @_ZN6test333fooINS_3zedEE3barEv
+ // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test333fooINS_3zedEE3barEv
+}
+
+namespace test34 {
+ struct foo {
+ };
+ template<class T>
+ void bar() {}
+ template DEFAULT void bar<foo>();
+ // CHECK-LABEL: define weak_odr void @_ZN6test343barINS_3fooEEEvv
+ // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test343barINS_3fooEEEvv
+}
+
+namespace test35 {
+ // This is a really ugly testcase. GCC propagates the DEFAULT in zed's
+ // definition. It's not really clear what we can do here, because we
+ // produce the symbols before even seeing the DEFAULT definition of zed.
+ // FIXME: Maybe the best thing to do here is error? It's certainly hard
+ // to argue that this ought to be valid.
+ template<typename T>
+ struct DEFAULT foo {
+ void bar() {}
+ };
+ class zed;
+ template class foo<zed>;
+ class DEFAULT zed {
+ };
+ // CHECK-LABEL: define weak_odr void @_ZN6test353fooINS_3zedEE3barEv
+ // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test353fooINS_3zedEE3barEv
+}
+
+namespace test36 {
+ template<typename T1, typename T2>
+ class foo {
+ void bar() {}
+ };
+ class DEFAULT S1 {};
+ struct HIDDEN S2 {};
+ template class foo<S1, S2>;
+ // CHECK-LABEL: define weak_odr hidden void @_ZN6test363fooINS_2S1ENS_2S2EE3barEv
+ // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test363fooINS_2S1ENS_2S2EE3barEv
+}
+
+namespace test37 {
+ struct HIDDEN foo {
+ };
+ template<class T>
+ DEFAULT void bar() {}
+ template DEFAULT void bar<foo>();
+ // CHECK-LABEL: define weak_odr void @_ZN6test373barINS_3fooEEEvv
+ // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test373barINS_3fooEEEvv
+}
+
+namespace test38 {
+ template<typename T>
+ class DEFAULT foo {
+ void bar() {}
+ };
+ struct HIDDEN zed {
+ };
+ template class foo<zed>;
+ // CHECK-LABEL: define weak_odr hidden void @_ZN6test383fooINS_3zedEE3barEv
+ // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test383fooINS_3zedEE3barEv
+}
+
+namespace test39 {
+ class DEFAULT default_t;
+ class HIDDEN hidden_t;
+ template <class T> class A {
+ template <class U> class B {
+ HIDDEN void hidden() {}
+ void noattr() {}
+ template <class V> void temp() {}
+ };
+ };
+ template class DEFAULT A<hidden_t>;
+ template class DEFAULT A<hidden_t>::B<hidden_t>;
+ template void A<hidden_t>::B<hidden_t>::temp<default_t>();
+ template void A<hidden_t>::B<hidden_t>::temp<hidden_t>();
+
+ // CHECK-LABEL: define weak_odr hidden void @_ZN6test391AINS_8hidden_tEE1BIS1_E6hiddenEv
+ // CHECK-LABEL: define weak_odr void @_ZN6test391AINS_8hidden_tEE1BIS1_E6noattrEv
+ // CHECK-LABEL: define weak_odr void @_ZN6test391AINS_8hidden_tEE1BIS1_E4tempINS_9default_tEEEvv
+
+ // GCC produces a default for this one. Why?
+ // CHECK-LABEL: define weak_odr hidden void @_ZN6test391AINS_8hidden_tEE1BIS1_E4tempIS1_EEvv
+
+ // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test391AINS_8hidden_tEE1BIS1_E6hiddenEv
+ // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test391AINS_8hidden_tEE1BIS1_E6noattrEv
+ // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test391AINS_8hidden_tEE1BIS1_E4tempINS_9default_tEEEvv
+
+ // GCC produces a default for this one. Why?
+ // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test391AINS_8hidden_tEE1BIS1_E4tempIS1_EEvv
+}
+
+namespace test42 {
+ struct HIDDEN foo {
+ };
+ template <class P>
+ struct bar {
+ };
+ template <>
+ struct HIDDEN bar<foo> {
+ DEFAULT static void zed();
+ };
+ void bar<foo>::zed() {
+ }
+ // CHECK-LABEL: define void @_ZN6test423barINS_3fooEE3zedEv
+ // CHECK-HIDDEN-LABEL: define void @_ZN6test423barINS_3fooEE3zedEv
+}
+
+namespace test43 {
+ struct HIDDEN foo {
+ };
+ template <class P>
+ void bar() {
+ }
+ template <>
+ DEFAULT void bar<foo>() {
+ }
+ // CHECK-LABEL: define void @_ZN6test433barINS_3fooEEEvv
+ // CHECK-HIDDEN-LABEL: define void @_ZN6test433barINS_3fooEEEvv
+}
+
+namespace test44 {
+ template <typename T>
+ struct foo {
+ foo() {}
+ };
+ namespace {
+ struct bar;
+ }
+ template struct DEFAULT foo<bar>;
+ foo<bar> x;
+ // CHECK-LABEL: define internal void @_ZN6test443fooINS_12_GLOBAL__N_13barEEC1Ev
+ // CHECK-HIDDEN-LABEL: define internal void @_ZN6test443fooINS_12_GLOBAL__N_13barEEC1Ev
+}
+
+namespace test45 {
+ template <typename T>
+ struct foo {
+ template <typename T2>
+ struct bar {
+ bar() {};
+ };
+ };
+ namespace {
+ struct zed;
+ }
+ template struct DEFAULT foo<int>::bar<zed>;
+ foo<int>::bar<zed> x;
+ // CHECK-LABEL: define internal void @_ZN6test453fooIiE3barINS_12_GLOBAL__N_13zedEEC1Ev
+ // CHECK-HIDDEN-LABEL: define internal void @_ZN6test453fooIiE3barINS_12_GLOBAL__N_13zedEEC1Ev
+}
+
+namespace test46 {
+ template <typename T>
+ void foo() {
+ }
+ namespace {
+ struct bar;
+ }
+ template DEFAULT void foo<bar>();
+ void zed() {
+ foo<bar>();
+ }
+ // CHECK-LABEL: define internal void @_ZN6test463fooINS_12_GLOBAL__N_13barEEEvv
+ // CHECK-HIDDEN-LABEL: define internal void @_ZN6test463fooINS_12_GLOBAL__N_13barEEEvv
+}
+
+namespace test47 {
+ struct foo {
+ template <typename T>
+ static void bar() {
+ }
+ };
+ namespace {
+ struct zed;
+ }
+ template DEFAULT void foo::bar<zed>();
+ void baz() {
+ foo::bar<zed>();
+ }
+ // CHECK-LABEL: define internal void @_ZN6test473foo3barINS_12_GLOBAL__N_13zedEEEvv
+ // CHECK-HIDDEN-LABEL: define internal void @_ZN6test473foo3barINS_12_GLOBAL__N_13zedEEEvv
+}
+
+namespace test49 {
+ // Test that we use the visibility of struct foo when instantiating the
+ // template. Note that is a case where we disagree with gcc, it produces
+ // a default symbol.
+
+ struct HIDDEN foo {
+ };
+
+ DEFAULT foo x;
+
+ struct bar {
+ template<foo *z>
+ void zed() {
+ }
+ };
+
+ template void bar::zed<&x>();
+ // CHECK-LABEL: define weak_odr hidden void @_ZN6test493bar3zedIXadL_ZNS_1xEEEEEvv
+ // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test493bar3zedIXadL_ZNS_1xEEEEEvv
+}
+
+namespace test50 {
+ // Test that we use the visibility of struct foo when instantiating the
+ // template. Note that is a case where we disagree with gcc, it produces
+ // a default symbol.
+
+ struct HIDDEN foo {
+ };
+ DEFAULT foo x;
+ template<foo *z>
+ struct DEFAULT bar {
+ void zed() {
+ }
+ };
+ template void bar<&x>::zed();
+ // CHECK-LABEL: define weak_odr hidden void @_ZN6test503barIXadL_ZNS_1xEEEE3zedEv
+ // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test503barIXadL_ZNS_1xEEEE3zedEv
+}
+
+namespace test51 {
+ // Test that we use the visibility of struct foo when instantiating the
+ // template. Note that is a case where we disagree with gcc, it produces
+ // a default symbol.
+
+ struct HIDDEN foo {
+ };
+ DEFAULT foo x;
+ template<foo *z>
+ void DEFAULT zed() {
+ }
+ template void zed<&x>();
+ // CHECK-LABEL: define weak_odr hidden void @_ZN6test513zedIXadL_ZNS_1xEEEEEvv
+ // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test513zedIXadL_ZNS_1xEEEEEvv
+}
+
+namespace test52 {
+ // Test that we use the linkage of struct foo when instantiating the
+ // template. Note that is a case where we disagree with gcc, it produces
+ // an external symbol.
+
+ namespace {
+ struct foo {
+ };
+ }
+ template<foo *x>
+ void zed() {
+ }
+ void f() {
+ zed<nullptr>();
+ }
+ // CHECK-LABEL: define internal void @_ZN6test523zedILPNS_12_GLOBAL__N_13fooE0EEEvv
+ // CHECK-HIDDEN-LABEL: define internal void @_ZN6test523zedILPNS_12_GLOBAL__N_13fooE0EEEvv
+}
+
+namespace test53 {
+ template<typename _Tp > struct vector {
+ static void _M_fill_insert();
+ };
+#pragma GCC visibility push(hidden)
+ // GCC doesn't seem to use the visibility of enums at all, we do.
+ enum zed {v1};
+
+ // GCC fails to mark this specialization hidden, we mark it.
+ template<>
+ struct vector<int> {
+ static void _M_fill_insert();
+ };
+ void foo() {
+ vector<unsigned>::_M_fill_insert();
+ vector<int>::_M_fill_insert();
+ vector<zed>::_M_fill_insert();
+ }
+#pragma GCC visibility pop
+ // CHECK: declare void @_ZN6test536vectorIjE14_M_fill_insertEv
+ // CHECK-HIDDEN: declare void @_ZN6test536vectorIjE14_M_fill_insertEv
+ // CHECK: declare hidden void @_ZN6test536vectorIiE14_M_fill_insertEv
+ // CHECK-HIDDEN: declare hidden void @_ZN6test536vectorIiE14_M_fill_insertEv
+ // CHECK: declare hidden void @_ZN6test536vectorINS_3zedEE14_M_fill_insertEv
+ // CHECK-HIDDEN: declare hidden void @_ZN6test536vectorINS_3zedEE14_M_fill_insertEv
+}
+
+namespace test54 {
+ template <class T>
+ struct foo {
+ static void bar();
+ };
+#pragma GCC visibility push(hidden)
+ class zed {
+ zed(const zed &);
+ };
+ void bah() {
+ foo<zed>::bar();
+ }
+#pragma GCC visibility pop
+ // CHECK: declare hidden void @_ZN6test543fooINS_3zedEE3barEv
+ // CHECK-HIDDEN: declare hidden void @_ZN6test543fooINS_3zedEE3barEv
+}
+
+namespace test55 {
+ template <class T>
+ struct HIDDEN foo {
+ static void bar();
+ };
+ template <class T> struct foo;
+ void foobar() {
+ foo<int>::bar();
+ }
+ // CHECK: declare hidden void @_ZN6test553fooIiE3barEv
+ // CHECK-HIDDEN: declare hidden void @_ZN6test553fooIiE3barEv
+}
+
+namespace test56 {
+ template <class T> struct foo;
+ template <class T>
+ struct HIDDEN foo {
+ static void bar();
+ };
+ void foobar() {
+ foo<int>::bar();
+ }
+ // CHECK: declare hidden void @_ZN6test563fooIiE3barEv
+ // CHECK-HIDDEN: declare hidden void @_ZN6test563fooIiE3barEv
+}
+
+namespace test57 {
+#pragma GCC visibility push(hidden)
+ template <class T>
+ struct foo;
+ void bar(foo<int>*);
+ template <class T>
+ struct foo {
+ static void zed();
+ };
+ void bah() {
+ foo<int>::zed();
+ }
+#pragma GCC visibility pop
+ // CHECK: declare hidden void @_ZN6test573fooIiE3zedEv
+ // CHECK-HIDDEN: declare hidden void @_ZN6test573fooIiE3zedEv
+}
+
+namespace test58 {
+#pragma GCC visibility push(hidden)
+ struct foo;
+ template<typename T>
+ struct DEFAULT bar {
+ static void zed() {
+ }
+ };
+ void bah() {
+ bar<foo>::zed();
+ }
+#pragma GCC visibility pop
+ // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test583barINS_3fooEE3zedEv
+ // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test583barINS_3fooEE3zedEv
+}
+
+namespace test59 {
+ DEFAULT int f();
+ HIDDEN int g();
+ typedef int (*foo)();
+ template<foo x, foo y>
+ void test() {}
+ void use() {
+ test<&g, &f>();
+ // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test594testIXadL_ZNS_1gEvEEXadL_ZNS_1fEvEEEEvv
+ // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test594testIXadL_ZNS_1gEvEEXadL_ZNS_1fEvEEEEvv
+
+ test<&f, &g>();
+ // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test594testIXadL_ZNS_1fEvEEXadL_ZNS_1gEvEEEEvv
+ // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test594testIXadL_ZNS_1fEvEEXadL_ZNS_1gEvEEEEvv
+ }
+}
+
+namespace test60 {
+ template<int i>
+ class HIDDEN a {};
+ template<int i>
+ class DEFAULT b {};
+ template<template<int> class x, template<int> class y>
+ void test() {}
+ void use() {
+ test<a, b>();
+ // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test604testINS_1aENS_1bEEEvv
+ // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test604testINS_1aENS_1bEEEvv
+
+ test<b, a>();
+ // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test604testINS_1bENS_1aEEEvv
+ // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test604testINS_1bENS_1aEEEvv
+ }
+}
+
+namespace test61 {
+ template <typename T1>
+ struct Class1
+ {
+ void f1() { f2(); }
+ inline void f2();
+ };
+ template<>
+ inline void Class1<int>::f2()
+ {
+ }
+ void g(Class1<int> *x) {
+ x->f1();
+ }
+}
+namespace test61 {
+ // Just test that we don't crash. Currently we apply this attribute. Current
+ // gcc issues a warning about it being unused since "the type is already
+ // defined". We should probably do the same.
+ template class HIDDEN Class1<int>;
+}
+
+namespace test62 {
+ template <typename T1>
+ struct Class1
+ {
+ void f1() { f2(); }
+ inline void f2() {}
+ };
+ template<>
+ inline void Class1<int>::f2()
+ {
+ }
+ void g(Class1<int> *x) {
+ x->f2();
+ }
+}
+namespace test62 {
+ template class HIDDEN Class1<int>;
+ // Just test that we don't crash. Currently we apply this attribute. Current
+ // gcc issues a warning about it being unused since "the type is already
+ // defined". We should probably do the same.
+}
+
+namespace test63 {
+ enum HIDDEN E { E0 };
+ struct A {
+ template <E> static void foo() {}
+
+ template <E> struct B {
+ static void foo() {}
+ };
+ };
+
+ void test() {
+ A::foo<E0>();
+ A::B<E0>::foo();
+ }
+ // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test631A3fooILNS_1EE0EEEvv()
+ // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test631A1BILNS_1EE0EE3fooEv()
+}
+
+// Don't ignore the visibility of template arguments just because we
+// explicitly instantiated something.
+namespace test64 {
+ struct HIDDEN A {};
+ template <class P> struct B {
+ static DEFAULT void foo() {}
+ };
+
+ template class B<A>;
+ // CHECK-LABEL: define weak_odr hidden void @_ZN6test641BINS_1AEE3fooEv()
+}
+
+namespace test65 {
+ class HIDDEN A {};
+ template <class T> struct B {
+ static void func();
+ template <class U> static void funcT1();
+ template <class U> static void funcT2();
+ class Inner {};
+ template <class U> class InnerT {};
+ };
+ template <template <class T> class Temp> struct C {
+ static void foo() {}
+ };
+
+ // CHECK-LABEL: define void @_ZN6test651BINS_1AEE4funcEv()
+ template <> DEFAULT void B<A>::func() {}
+
+ // CHECK-LABEL: define void @_ZN6test651BINS_1AEE6funcT2IS1_EEvv()
+ template <> template <> DEFAULT void B<A>::funcT2<A>() {}
+
+ // CHECK-LABEL: define linkonce_odr void @_ZN6test651BINS_1AEE6funcT1IiEEvv()
+ // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test651BINS_1AEE6funcT1IS1_EEvv()
+ template <> template <class T> DEFAULT void B<A>::funcT1() {}
+
+ // CHECK-LABEL: define linkonce_odr void @_ZN6test651BINS_1AEE5Inner3fooEv()
+ template <> struct DEFAULT B<A>::Inner {
+ static void foo() {}
+ };
+
+ // CHECK-LABEL: define linkonce_odr void @_ZN6test651BINS_1AEE6InnerTIiE3fooEv()
+ // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test651BINS_1AEE6InnerTIS1_E3fooEv()
+ template <> template <class U> struct DEFAULT B<A>::InnerT {
+ static void foo() {}
+ };
+
+ void test() {
+ B<A>::funcT1<int>();
+ B<A>::funcT1<A>();
+ B<A>::Inner::foo();
+ B<A>::InnerT<int>::foo();
+ B<A>::InnerT<A>::foo();
+ }
+
+ template class C<B<A>::InnerT>;
+}
+
+namespace test66 {
+ template <typename T>
+ struct DEFAULT barT {
+ static void zed() {}
+ };
+ class foo;
+ class DEFAULT foo;
+ template struct barT<foo>;
+ // CHECK-LABEL: define weak_odr void @_ZN6test664barTINS_3fooEE3zedEv
+ // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test664barTINS_3fooEE3zedEv
+
+ template <int* I>
+ struct DEFAULT barI {
+ static void zed() {}
+ };
+ extern int I;
+ extern int I DEFAULT;
+ template struct barI<&I>;
+ // CHECK-LABEL: define weak_odr void @_ZN6test664barIIXadL_ZNS_1IEEEE3zedEv
+ // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test664barIIXadL_ZNS_1IEEEE3zedEv
+
+ typedef void (*fType)(void);
+ template<fType F>
+ struct DEFAULT barF {
+ static void zed() {}
+ };
+ void F();
+ void F() DEFAULT;
+ template struct barF<F>;
+ // CHECK-LABEL: define weak_odr void @_ZN6test664barFIXadL_ZNS_1FEvEEE3zedEv
+ // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test664barFIXadL_ZNS_1FEvEEE3zedEv
+}
+
+namespace test67 {
+ template <typename T>
+ struct DEFAULT bar {
+ static void zed() {}
+ };
+
+ class foo;
+ class compute {
+ void f(foo *rootfoo);
+ };
+ class DEFAULT foo;
+
+ template struct bar<foo>;
+ // CHECK-LABEL: define weak_odr void @_ZN6test673barINS_3fooEE3zedEv
+ // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test673barINS_3fooEE3zedEv
+}
+
+namespace test68 {
+ class A { public: ~A(); };
+ class f {
+ public:
+ f() {
+ static A test;
+ }
+ };
+ void g() {
+ f a;
+ }
+ // Check lines at top of file.
+}
+
+namespace test69 {
+ // PR18174
+ namespace foo {
+ void f();
+ }
+ namespace foo {
+ void f() {};
+ }
+ namespace foo __attribute__((visibility("hidden"))) {
+ }
+ // CHECK-LABEL: define void @_ZN6test693foo1fEv
+ // CHECK-HIDDEN-LABEL: define hidden void @_ZN6test693foo1fEv
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/vla-consruct.cpp b/src/llvm-project/clang/test/CodeGenCXX/vla-consruct.cpp
new file mode 100644
index 0000000..87191fe
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/vla-consruct.cpp
@@ -0,0 +1,143 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fcxx-exceptions -fexceptions -O0 %s -emit-llvm -o - | FileCheck %s
+
+extern "C" int printf(const char *, ...);
+
+static int N;
+struct S {
+ S()
+ __attribute__((nothrow)) { printf("%d: S()\n", ++N); }
+ ~S() __attribute__((nothrow)) { printf("%d: ~S()\n", N--); }
+ int n[17];
+};
+// CHECK: [[struct_S:%.+]] = type { [17 x i32] }
+void print(int n, int a, int b, int c, int d) {
+ printf("n=%d\n,sizeof(S)=%d\nsizeof(array_t[0][0])=%d\nsizeof(array_t[0])=%d\nsizeof(array_t)=%d\n",
+ n, a, b, c, d);
+ if (n == 2)
+ throw(n);
+}
+
+void test(int n) {
+ // CHECK: define void {{.*test.*}}(i32 [[n:%.+]]) #
+ // CHECK: [[n_addr:%.+]] = alloca
+ // CHECK-NEXT: [[saved_stack:%.+]] = alloca
+ // CHECK-NEXT: [[vla_expr:%.+]] = alloca i64, align 8
+ // CHECK-NEXT: [[vla_expr1:%.+]] = alloca i64, align 8
+ // CHECK-NEXT: [[sizeof_S:%.+]] = alloca
+ // CHECK-NEXT: [[sizeof_array_t_0_0:%.+]] = alloca
+ // CHECK-NEXT: [[sizeof_array_t_0:%.+]] = alloca
+ // CHECK-NEXT: [[sizeof_array_t:%.+]] = alloca
+ // CHECK-NEXT: [[exn_slot:%.+]] = alloca i8*
+ // CHECK-NEXT: [[ehselector_slot:%.+]] = alloca i32
+ // CHECK-NEXT: store i32 [[n]], i32* [[n_addr]]
+ // CHECK-NEXT: [[t0:%.+]] = load i32, i32* [[n_addr]]
+ // CHECK-NEXT: [[t1:%.+]] = zext i32 [[t0]] to i64
+ // CHECK-NEXT: [[t2:%.+]] = load i32, i32* [[n_addr]]
+ // CHECK-NEXT: [[add:%.+]] = add nsw i32 [[t2]], 1
+ // CHECK-NEXT: [[t3:%.+]] = zext i32 [[add]] to i64
+ // CHECK-NEXT: [[t4:%.+]] = call i8* @llvm.stacksave()
+ // CHECK-NEXT: store i8* [[t4]], i8** [[saved_stack]]
+ // CHECK-NEXT: [[t5:%.+]] = mul nuw i64 [[t1]], [[t3]]
+ // CHECK-NEXT: [[vla:%.+]] = alloca [[struct_S]], i64 [[t5]]
+ // CHECK-NEXT: store i64 [[t1]], i64* [[vla_expr]]
+ // CHECK-NEXT: store i64 [[t3]], i64* [[vla_expr1]]
+ // CHECK-NEXT: [[t6:%.+]] = mul nuw i64 [[t1]], [[t3]]
+ // CHECK-NEXT: [[isempty:%.+]] = icmp eq i64 [[t6]], 0
+ // CHECK-NEXT: br i1 [[isempty]], label %[[arrayctor_cont:.+]], label %[[new_ctorloop:.+]]
+
+ S array_t[n][n + 1];
+
+ // CHECK: [[new_ctorloop]]
+ // CHECK-NEXT: [[arrayctor_end:%.+]] = getelementptr inbounds [[struct_S]], [[struct_S]]* [[vla]], i64 [[t6]]
+ // CHECK-NEXT: br label %[[arrayctor_loop:.+]]
+
+ // CHECK: [[arrayctor_loop]]
+ // CHECK-NEXT: [[arrayctor_cur:%.+]] = phi [[struct_S]]* [ [[vla]], %[[new_ctorloop]] ], [ [[arrayctor_next:%.+]], %[[arrayctor_loop]] ]
+ // CHECK-NEXT: call void [[ctor:@.+]]([[struct_S]]* [[arrayctor_cur]])
+ // CHECK-NEXT: [[arrayctor_next]] = getelementptr inbounds [[struct_S]], [[struct_S]]* [[arrayctor_cur]], i64 1
+ // CHECK-NEXT: [[arrayctor_done:%.+]] = icmp eq [[struct_S]]* [[arrayctor_next]], [[arrayctor_end]]
+ // CHECK-NEXT: br i1 [[arrayctor_done]], label %[[arrayctor_cont]], label %[[arrayctor_loop]]
+
+ int sizeof_S = sizeof(S);
+ int sizeof_array_t_0_0 = sizeof(array_t[0][0]);
+ int sizeof_array_t_0 = sizeof(array_t[0]);
+ int sizeof_array_t = sizeof(array_t);
+ print(n, sizeof_S, sizeof_array_t_0_0, sizeof_array_t_0, sizeof_array_t);
+
+ // CHECK: [[arrayctor_cont]]
+ // CHECK-NEXT: store i32 68, i32* [[sizeof_S]]
+ // CHECK-NEXT: store i32 68, i32* [[sizeof_array_t_0_0]]
+ // CHECK: [[t8:%.+]] = mul nuw i64 68, [[t3]]
+ // CHECK-NEXT: [[conv:%.+]] = trunc i64 [[t8]] to i32
+ // CHECK-NEXT: store i32 [[conv]], i32* [[sizeof_array_t_0]]
+ // CHECK-NEXT: [[t9:%.+]] = mul nuw i64 [[t1]], [[t3]]
+ // CHECK-NEXT: [[t10:%.+]] = mul nuw i64 68, [[t9]]
+ // CHECK-NEXT: [[conv1:%.+]] = trunc i64 [[t10]] to i32
+ // CHECK-NEXT: store i32 [[conv1]], i32* [[sizeof_array_t]]
+ // CHECK-NEXT: [[t11:%.+]] = load i32, i32* [[n_addr:%.+]]
+ // CHECK-NEXT: [[t12:%.+]] = load i32, i32* [[sizeof_S]]
+ // CHECK-NEXT: [[t13:%.+]] = load i32, i32* [[sizeof_array_t_0_0]]
+ // CHECK-NEXT: [[t14:%.+]] = load i32, i32* [[sizeof_array_t_0]]
+ // CHECK-NEXT: [[t15:%.+]] = load i32, i32* [[sizeof_array_t]]
+ // CHECK-NEXT: invoke void @{{.*print.*}}(i32 [[t11]], i32 [[t12]], i32 [[t13]], i32 [[t14]], i32 [[t15]])
+ // CHECK-NEXT: to label %[[invoke_cont:.+]] unwind label %[[lpad:.+]]
+
+ // CHECK: [[invoke_cont]]
+ // CHECK-NEXT: [[t16:%.+]] = mul nuw i64 [[t1]], [[t3]]
+ // CHECK-NEXT: [[t17:%.+]] = getelementptr inbounds [[struct_S]], [[struct_S]]* [[vla]], i64 [[t16]]
+ // CHECK-NEXT: [[arraydestroy_isempty:%.+]] = icmp eq [[struct_S]]* [[vla]], [[t17]]
+ // CHECK-NEXT: br i1 [[arraydestroy_isempty]], label %[[arraydestroy_done2:.+]], label %[[arraydestroy_body:.+]]
+
+ // CHECK: [[arraydestroy_body]]
+ // CHECK-NEXT: [[arraydestroy_elementPast:%.+]] = phi [[struct_S]]* [ [[t17]], %[[invoke_cont]] ], [ [[arraydestroy_element:%.+]], %[[arraydestroy_body]] ]
+ // CHECK-NEXT: [[arraydestroy_element]] = getelementptr inbounds [[struct_S]], [[struct_S]]* [[arraydestroy_elementPast]]
+ // CHECK-NEXT: call void @[[dtor:.+]]([[struct_S]]* [[arraydestroy_element]])
+ // CHECK-NEXT: [[arraydestroy_done:%.+]] = icmp eq [[struct_S]]* [[arraydestroy_element]], [[vla]]
+ // CHECK-NEXT: br i1 [[arraydestroy_done]], label %[[arraydestroy_done2]], label %[[arraydestroy_body]]
+
+ // CHECK: [[arraydestroy_done2]]
+ // CHECK-NEXT: [[t17:%.+]] = load i8*, i8** [[saved_stack]]
+ // CHECK-NEXT: call void @llvm.stackrestore(i8* [[t17]])
+ // CHECK: ret void
+
+ // CHECK: [[lpad]]
+ // CHECK-NEXT: [[t19:%.+]] = landingpad { i8*, i32 }
+ // CHECK: [[t20:%.+]] = extractvalue { i8*, i32 } [[t19]], 0
+ // CHECK-NEXT: store i8* [[t20]], i8** [[exn_slot]]
+ // CHECK-NEXT: [[t21:%.+]] = extractvalue { i8*, i32 } [[t19]], 1
+ // CHECK-NEXT: store i32 [[t21]], i32* [[ehselector_slot]]
+ // CHECK-NEXT: [[t22:%.+]] = mul nuw i64 [[t1]], [[t3]]
+ // CHECK-NEXT: [[t23:%.+]] = getelementptr inbounds [[struct_S]], [[struct_S]]* [[vla]], i64 [[t22]]
+ // CHECK-NEXT: [[arraydestroy_isempty3:%.+]] = icmp eq [[struct_S]]* [[vla]], [[t23]]
+ // CHECK-NEXT: br i1 [[arraydestroy_isempty3]], label %[[arraydestroy_done8:.+]], label %[[arraydestroy_body4:.+]]
+
+ // CHECK: [[arraydestroy_body4]]
+ // CHECK: [[arraydestroy_elementPast5:%.+]] = phi [[struct_S]]* [ [[t23]], %[[lpad]] ], [ [[arraydestroy_element6:.+]], %[[arraydestroy_body4]] ]
+ // CHECK-NEXT: [[arraydestroy_element6]] = getelementptr inbounds [[struct_S]], [[struct_S]]* [[arraydestroy_elementPast5]], i64 -1
+ // CHECK-NEXT: call void @[[dtor]]([[struct_S]]* [[arraydestroy_element6]])
+ // CHECK-NEXT: [[arraydestroy_done7:%.+]] = icmp eq [[struct_S]]* [[arraydestroy_element6]], [[vla]]
+ // CHECK-NEXT: br i1 [[arraydestroy_done7]], label %[[arraydestroy_done8]], label %[[arraydestroy_body4]]
+
+ // CHECK: [[arraydestroy_done8]]
+ // CHECK-NEXT: br label %[[eh_resume:.+]]
+
+ // CHECK: [[eh_resume]]
+ // CHECK-NEXT: [[exn:%.+]] = load i8*, i8** [[exn_slot]]
+ // CHECK-NEXT: [[sel:%.+]] = load i32, i32* [[ehselector_slot]]
+ // CHECK-NEXT: [[lpad_val:%.+]] = insertvalue { i8*, i32 } undef, i8* [[exn]], 0
+ // CHECK-NEXT: [[lpad_val9:%.+]] = insertvalue { i8*, i32 } [[lpad_val]], i32 [[sel]], 1
+ // CHECK-NEXT: resume { i8*, i32 } [[lpad_val9]]
+}
+
+int main() {
+ try {
+ test(2);
+ } catch (int e) {
+ printf("expeption %d\n", e);
+ }
+ try {
+ test(3);
+ } catch (int e) {
+ printf("expeption %d", e);
+ }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/vla-lambda-capturing.cpp b/src/llvm-project/clang/test/CodeGenCXX/vla-lambda-capturing.cpp
new file mode 100644
index 0000000..5081f14
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/vla-lambda-capturing.cpp
@@ -0,0 +1,171 @@
+// RUN: %clang_cc1 %s -std=c++11 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -std=c++11 -emit-pch -o %t
+// RUN: %clang_cc1 %s -std=c++11 -include-pch %t -emit-llvm -o - | FileCheck %s
+
+#ifndef HEADER
+#define HEADER
+
+typedef __INTPTR_TYPE__ intptr_t;
+
+// CHECK-DAG: [[CAP_TYPE1:%.+]] = type { [[INTPTR_T:i.+]], [[INTPTR_T]]*, [[INTPTR_T]]* }
+// CHECK-DAG: [[CAP_TYPE2:%.+]] = type { [[INTPTR_T]], [[INTPTR_T]]* }
+// CHECK-DAG: [[CAP_TYPE3:%.+]] = type { [[INTPTR_T]]*, [[INTPTR_T]], [[INTPTR_T]], [[INTPTR_T]]*, [[INTPTR_T]]* }
+// CHECK-DAG: [[CAP_TYPE4:%.+]] = type { [[INTPTR_T]]*, [[INTPTR_T]], [[INTPTR_T]]*, [[INTPTR_T]], [[INTPTR_T]]* }
+
+// CHECK: define {{.*}}void [[G:@.+]](
+// CHECK: [[N_ADDR:%.+]] = alloca [[INTPTR_T]]
+// CHECK: store [[INTPTR_T]] %{{.+}}, [[INTPTR_T]]* [[N_ADDR]]
+// CHECK: [[N_VAL:%.+]] = load [[INTPTR_T]], [[INTPTR_T]]* [[N_ADDR]]
+// CHECK: [[CAP_EXPR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE1]], [[CAP_TYPE1]]* [[CAP_ARG:%.+]], i{{.+}} 0, i{{.+}} 0
+// CHECK: store [[INTPTR_T]] [[N_VAL]], [[INTPTR_T]]* [[CAP_EXPR_REF]]
+// CHECK: [[CAP_BUFFER_ADDR:%.+]] = getelementptr inbounds [[CAP_TYPE1]], [[CAP_TYPE1]]* [[CAP_ARG]], i{{.+}} 0, i{{.+}} 1
+// CHECK: store [[INTPTR_T]]* %{{.+}}, [[INTPTR_T]]** [[CAP_BUFFER_ADDR]]
+// CHECK: [[CAP_N_REF:%.+]] = getelementptr inbounds [[CAP_TYPE1]], [[CAP_TYPE1]]* [[CAP_ARG:%.+]], i{{.+}} 0, i{{.+}} 2
+// CHECK: store [[INTPTR_T]]* [[N_ADDR]], [[INTPTR_T]]** [[CAP_N_REF]]
+// CHECK: call{{.*}} void [[G_LAMBDA:@.+]]([[CAP_TYPE1]]* [[CAP_ARG]])
+// CHECK: ret void
+void g(intptr_t n) {
+ intptr_t buffer[n];
+ [&buffer, &n]() {
+ __typeof(buffer) x;
+ }();
+}
+
+// CHECK: void [[G_LAMBDA]]([[CAP_TYPE1]]*
+// CHECK: [[THIS:%.+]] = load [[CAP_TYPE1]]*, [[CAP_TYPE1]]**
+// CHECK: [[N_ADDR:%.+]] = getelementptr inbounds [[CAP_TYPE1]], [[CAP_TYPE1]]* [[THIS]], i{{.+}} 0, i{{.+}} 0
+// CHECK: [[N:%.+]] = load [[INTPTR_T]], [[INTPTR_T]]* [[N_ADDR]]
+// CHECK: [[BUFFER_ADDR:%.+]] = getelementptr inbounds [[CAP_TYPE1]], [[CAP_TYPE1]]* [[THIS]], i{{.+}} 0, i{{.+}} 1
+// CHECK: [[BUFFER:%.+]] = load [[INTPTR_T]]*, [[INTPTR_T]]** [[BUFFER_ADDR]]
+// CHECK: call i{{.+}}* @llvm.stacksave()
+// CHECK: alloca [[INTPTR_T]], [[INTPTR_T]] [[N]]
+// CHECK: call void @llvm.stackrestore(
+// CHECK: ret void
+
+template <typename T>
+void f(T n, T m) {
+ intptr_t buffer[n + m];
+ [&buffer]() {
+ __typeof(buffer) x;
+ }();
+}
+
+template <typename T>
+intptr_t getSize(T);
+
+template <typename T>
+void b(intptr_t n, T arg) {
+ typedef intptr_t ArrTy[getSize(arg)];
+ ArrTy buffer2;
+ ArrTy buffer1[n + arg];
+ intptr_t a;
+ [&]() {
+ n = sizeof(buffer1[n]);
+ [&](){
+ n = sizeof(buffer2);
+ n = sizeof(buffer1);
+ }();
+ }();
+}
+
+// CHECK-LABEL: @main
+int main() {
+ // CHECK: call {{.*}}void [[G]]([[INTPTR_T]] [[INTPTR_T_ATTR:(signext )?]]1)
+ g((intptr_t)1);
+ // CHECK: call {{.*}}void [[F_INT:@.+]]([[INTPTR_T]] [[INTPTR_T_ATTR]]1, [[INTPTR_T]] [[INTPTR_T_ATTR]]2)
+ f((intptr_t)1, (intptr_t)2);
+ // CHECK: call {{.*}}void [[B_INT:@.+]]([[INTPTR_T]] [[INTPTR_T_ATTR]]12, [[INTPTR_T]] [[INTPTR_T_ATTR]]13)
+ b((intptr_t)12, (intptr_t)13);
+ // CHECK: ret i32 0
+ return 0;
+}
+
+// CHECK: define linkonce_odr {{.*}}void [[F_INT]]([[INTPTR_T]]
+// CHECK: [[SIZE:%.+]] = add
+// CHECK: call i{{.+}}* @llvm.stacksave()
+// CHECK: [[BUFFER_ADDR:%.+]] = alloca [[INTPTR_T]], [[INTPTR_T]] [[SIZE]]
+// CHECK: [[CAP_SIZE_REF:%.+]] = getelementptr inbounds [[CAP_TYPE2]], [[CAP_TYPE2]]* [[CAP_ARG:%.+]], i{{.+}} 0, i{{.+}} 0
+// CHECK: store [[INTPTR_T]] [[SIZE]], [[INTPTR_T]]* [[CAP_SIZE_REF]]
+// CHECK: [[CAP_BUFFER_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE2]], [[CAP_TYPE2]]* [[CAP_ARG]], i{{.+}} 0, i{{.+}} 1
+// CHECK: store [[INTPTR_T]]* [[BUFFER_ADDR]], [[INTPTR_T]]** [[CAP_BUFFER_ADDR_REF]]
+// CHECK: call{{.*}} void [[F_INT_LAMBDA:@.+]]([[CAP_TYPE2]]* [[CAP_ARG]])
+// CHECK: call void @llvm.stackrestore(
+// CHECK: ret void
+// CHECK: void [[B_INT]]([[INTPTR_T]]
+// CHECK: [[SIZE1:%.+]] = call {{.*}}[[INTPTR_T]]
+// CHECK: call i{{.+}}* @llvm.stacksave()
+// CHECK: [[BUFFER2_ADDR:%.+]] = alloca [[INTPTR_T]], [[INTPTR_T]] [[SIZE1]]
+// CHECK: [[SIZE2:%.+]] = add
+// CHECK: [[BUFFER1_ADDR:%.+]] = alloca [[INTPTR_T]], [[INTPTR_T]]
+// CHECK: [[CAP_N_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]], [[CAP_TYPE3]]* [[CAP_ARG:%.+]], i{{.+}} 0, i{{.+}} 0
+// CHECK: store [[INTPTR_T]]* {{%.+}}, [[INTPTR_T]]** [[CAP_N_ADDR_REF]]
+// CHECK: [[CAP_SIZE2_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]], [[CAP_TYPE3]]* [[CAP_ARG]], i{{.+}} 0, i{{.+}} 1
+// CHECK: store i{{[0-9]+}} [[SIZE2]], i{{[0-9]+}}* [[CAP_SIZE2_REF]]
+// CHECK: [[CAP_SIZE1_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]], [[CAP_TYPE3]]* [[CAP_ARG]], i{{.+}} 0, i{{.+}} 2
+// CHECK: store i{{[0-9]+}} [[SIZE1]], i{{[0-9]+}}* [[CAP_SIZE1_REF]]
+// CHECK: [[CAP_BUFFER1_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]], [[CAP_TYPE3]]* [[CAP_ARG]], i{{.+}} 0, i{{.+}} 3
+// CHECK: store [[INTPTR_T]]* [[BUFFER1_ADDR]], [[INTPTR_T]]** [[CAP_BUFFER1_ADDR_REF]]
+// CHECK: [[CAP_BUFFER2_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]], [[CAP_TYPE3]]* [[CAP_ARG]], i{{.+}} 0, i{{.+}} 4
+// CHECK: store [[INTPTR_T]]* [[BUFFER2_ADDR]], [[INTPTR_T]]** [[CAP_BUFFER2_ADDR_REF]]
+// CHECK: call{{.*}} void [[B_INT_LAMBDA:@.+]]([[CAP_TYPE3]]* [[CAP_ARG]])
+// CHECK: call void @llvm.stackrestore(
+// CHECK: ret void
+
+// CHECK: define linkonce_odr{{.*}} void [[F_INT_LAMBDA]]([[CAP_TYPE2]]*
+// CHECK: [[THIS:%.+]] = load [[CAP_TYPE2]]*, [[CAP_TYPE2]]**
+// CHECK: [[SIZE_REF:%.+]] = getelementptr inbounds [[CAP_TYPE2]], [[CAP_TYPE2]]* [[THIS]], i{{.+}} 0, i{{.+}} 0
+// CHECK: [[SIZE:%.+]] = load [[INTPTR_T]], [[INTPTR_T]]* [[SIZE_REF]]
+// CHECK: call i{{.+}}* @llvm.stacksave()
+// CHECK: alloca [[INTPTR_T]], [[INTPTR_T]] [[SIZE]]
+// CHECK: call void @llvm.stackrestore(
+// CHECK: ret void
+
+// CHECK: define linkonce_odr{{.*}} void [[B_INT_LAMBDA]]([[CAP_TYPE3]]*
+// CHECK: [[SIZE2_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]], [[CAP_TYPE3]]* [[THIS:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+// CHECK: [[SIZE2:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIZE2_REF]]
+// CHECK: [[SIZE1_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]], [[CAP_TYPE3]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+// CHECK: [[SIZE1:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIZE1_REF]]
+// CHECK: [[BUFFER1_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]], [[CAP_TYPE3]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
+// CHECK: [[BUFFER1_ADDR:%.+]] = load [[INTPTR_T]]*, [[INTPTR_T]]** [[BUFFER1_ADDR_REF]]
+// CHECK: [[N_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]], [[CAP_TYPE3]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[N_ADDR:%.+]] = load [[INTPTR_T]]*, [[INTPTR_T]]** [[N_ADDR_REF]]
+// CHECK: [[N:%.+]] = load [[INTPTR_T]], [[INTPTR_T]]* [[N_ADDR]]
+// CHECK: [[ELEM_OFFSET:%.+]] = mul {{.*}} i{{[0-9]+}} [[N]], [[SIZE1]]
+// CHECK: [[ELEM_ADDR:%.+]] = getelementptr inbounds [[INTPTR_T]], [[INTPTR_T]]* [[BUFFER1_ADDR]], i{{[0-9]+}} [[ELEM_OFFSET]]
+// CHECK: [[SIZEOF:%.+]] = mul {{.*}} i{{[0-9]+}} {{[0-9]+}}, [[SIZE1]]
+// CHECK: [[N_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]], [[CAP_TYPE3]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[N_ADDR:%.+]] = load [[INTPTR_T]]*, [[INTPTR_T]]** [[N_ADDR_REF]]
+// CHECK: store [[INTPTR_T]] {{%.+}}, [[INTPTR_T]]* [[N_ADDR]]
+// CHECK: [[N_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE4]], [[CAP_TYPE4]]* [[CAP:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[N_ADDR_REF_ORIG:%.+]] = getelementptr inbounds [[CAP_TYPE3]], [[CAP_TYPE3]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[N_ADDR_ORIG:%.+]] = load [[INTPTR_T]]*, [[INTPTR_T]]** [[N_ADDR_REF_ORIG]]
+// CHECK: store [[INTPTR_T]]* [[N_ADDR_ORIG]], [[INTPTR_T]]** [[N_ADDR_REF]]
+// CHECK: [[SIZE1_REF:%.+]] = getelementptr inbounds [[CAP_TYPE4]], [[CAP_TYPE4]]* [[CAP]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+// CHECK: store i{{[0-9]+}} [[SIZE1]], i{{[0-9]+}}* [[SIZE1_REF]]
+// CHECK: [[BUFFER2_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE4]], [[CAP_TYPE4]]* [[CAP]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+// CHECK: [[BUFFER2_ADDR_REF_ORIG:%.+]] = getelementptr inbounds [[CAP_TYPE3]], [[CAP_TYPE3]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 4
+// CHECK: [[BUFFER2_ADDR_ORIG:%.+]] = load [[INTPTR_T]]*, [[INTPTR_T]]** [[BUFFER2_ADDR_REF_ORIG]]
+// CHECK: store [[INTPTR_T]]* [[BUFFER2_ADDR_ORIG]], [[INTPTR_T]]** [[BUFFER2_ADDR_REF]]
+// CHECK: [[SIZE2_REF:%.+]] = getelementptr inbounds [[CAP_TYPE4]], [[CAP_TYPE4]]* [[CAP]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
+// CHECK: store i{{[0-9]+}} [[SIZE2]], i{{[0-9]+}}* [[SIZE2_REF]]
+// CHECK: [[BUFFER1_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE4]], [[CAP_TYPE4]]* [[CAP]], i{{[0-9]+}} 0, i{{[0-9]+}} 4
+// CHECK: [[BUFFER1_ADDR_REF_ORIG:%.+]] = getelementptr inbounds [[CAP_TYPE3]], [[CAP_TYPE3]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
+// CHECK: [[BUFFER1_ADDR_ORIG:%.+]] = load [[INTPTR_T]]*, [[INTPTR_T]]** [[BUFFER1_ADDR_REF_ORIG]]
+// CHECK: store [[INTPTR_T]]* [[BUFFER1_ADDR_ORIG]], [[INTPTR_T]]** [[BUFFER1_ADDR_REF]]
+// CHECK: call{{.*}} void [[B_INT_LAMBDA_LAMBDA:@.+]]([[CAP_TYPE4]]* [[CAP]])
+// CHECK: ret void
+
+// CHECK: define linkonce_odr{{.*}} void [[B_INT_LAMBDA_LAMBDA]]([[CAP_TYPE4]]*
+// CHECK: [[SIZE1_REF:%.+]] = getelementptr inbounds [[CAP_TYPE4]], [[CAP_TYPE4]]* [[THIS:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+// CHECK: [[SIZE1:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIZE1_REF]]
+// CHECK: [[SIZE2_REF:%.+]] = getelementptr inbounds [[CAP_TYPE4]], [[CAP_TYPE4]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
+// CHECK: [[SIZE2:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIZE2_REF]]
+// CHECK: [[BUFFER2_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE4]], [[CAP_TYPE4]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+// CHECK: [[BUFFER2_ADDR:%.+]] = load [[INTPTR_T]]*, [[INTPTR_T]]** [[BUFFER2_ADDR_REF]]
+// CHECK: [[SIZEOF_BUFFER2:%.+]] = mul {{.*}} i{{[0-9]+}} {{[0-9]+}}, [[SIZE1]]
+// CHECK: [[BUFFER1_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE4]], [[CAP_TYPE4]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 4
+// CHECK: [[BUFFER1_ADDR:%.+]] = load [[INTPTR_T]]*, [[INTPTR_T]]** [[BUFFER1_ADDR_REF]]
+// CHECK: [[MUL:%.+]] = mul {{.*}} i{{[0-9]+}} [[SIZE2]], [[SIZE1]]
+// CHECK: mul {{.*}} i{{[0-9]+}} {{[0-9]+}}, [[MUL]]
+// CHECK: ret void
+#endif
diff --git a/src/llvm-project/clang/test/CodeGenCXX/vla.cpp b/src/llvm-project/clang/test/CodeGenCXX/vla.cpp
new file mode 100644
index 0000000..81ff62d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/vla.cpp
@@ -0,0 +1,128 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin %s -emit-llvm -o - | FileCheck -check-prefixes=X64,CHECK %s
+// RUN: %clang_cc1 -std=c++11 -triple amdgcn %s -emit-llvm -o - | FileCheck -check-prefixes=AMDGCN,CHECK %s
+
+template<typename T>
+struct S {
+ static int n;
+};
+template<typename T> int S<T>::n = 5;
+
+int f() {
+ // Make sure that the reference here is enough to trigger the instantiation of
+ // the static data member.
+ // CHECK: @_ZN1SIiE1nE = linkonce_odr{{.*}} global i32 5
+ int a[S<int>::n];
+ return sizeof a;
+}
+
+// rdar://problem/9506377
+void test0(void *array, int n) {
+ // CHECK-LABEL: define void @_Z5test0Pvi(
+ // X64: [[ARRAY:%.*]] = alloca i8*, align 8
+ // AMDGCN: [[ARRAY0:%.*]] = alloca i8*, align 8, addrspace(5)
+ // AMDGCN-NEXT: [[ARRAY:%.*]] = addrspacecast i8* addrspace(5)* [[ARRAY0]] to i8**
+ // X64-NEXT: [[N:%.*]] = alloca i32, align 4
+ // AMDGCN: [[N0:%.*]] = alloca i32, align 4, addrspace(5)
+ // AMDGCN-NEXT: [[N:%.*]] = addrspacecast i32 addrspace(5)* [[N0]] to i32*
+ // X64-NEXT: [[REF:%.*]] = alloca i16*, align 8
+ // AMDGCN: [[REF0:%.*]] = alloca i16*, align 8, addrspace(5)
+ // AMDGCN-NEXT: [[REF:%.*]] = addrspacecast i16* addrspace(5)* [[REF0]] to i16**
+ // X64-NEXT: [[S:%.*]] = alloca i16, align 2
+ // AMDGCN: [[S0:%.*]] = alloca i16, align 2, addrspace(5)
+ // AMDGCN-NEXT: [[S:%.*]] = addrspacecast i16 addrspace(5)* [[S0]] to i16*
+ // CHECK-NEXT: store i8*
+ // CHECK-NEXT: store i32
+
+ // Capture the bounds.
+ // CHECK-NEXT: [[T0:%.*]] = load i32, i32* [[N]], align 4
+ // CHECK-NEXT: [[DIM0:%.*]] = zext i32 [[T0]] to i64
+ // CHECK-NEXT: [[T0:%.*]] = load i32, i32* [[N]], align 4
+ // CHECK-NEXT: [[T1:%.*]] = add nsw i32 [[T0]], 1
+ // CHECK-NEXT: [[DIM1:%.*]] = zext i32 [[T1]] to i64
+ typedef short array_t[n][n+1];
+
+ // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[ARRAY]], align 8
+ // CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to i16*
+ // CHECK-NEXT: store i16* [[T1]], i16** [[REF]], align 8
+ array_t &ref = *(array_t*) array;
+
+ // CHECK-NEXT: [[T0:%.*]] = load i16*, i16** [[REF]]
+ // CHECK-NEXT: [[T1:%.*]] = mul nsw i64 1, [[DIM1]]
+ // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds i16, i16* [[T0]], i64 [[T1]]
+ // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i16, i16* [[T2]], i64 2
+ // CHECK-NEXT: store i16 3, i16* [[T3]]
+ ref[1][2] = 3;
+
+ // CHECK-NEXT: [[T0:%.*]] = load i16*, i16** [[REF]]
+ // CHECK-NEXT: [[T1:%.*]] = mul nsw i64 4, [[DIM1]]
+ // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds i16, i16* [[T0]], i64 [[T1]]
+ // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i16, i16* [[T2]], i64 5
+ // CHECK-NEXT: [[T4:%.*]] = load i16, i16* [[T3]]
+ // CHECK-NEXT: store i16 [[T4]], i16* [[S]], align 2
+ short s = ref[4][5];
+
+ // CHECK-NEXT: ret void
+}
+
+
+void test2(int b) {
+ // CHECK-LABEL: define void {{.*}}test2{{.*}}(i32 %b)
+ int varr[b];
+ // AMDGCN: %__end1 = alloca i32*, align 8, addrspace(5)
+ // AMDGCN: [[END:%.*]] = addrspacecast i32* addrspace(5)* %__end1 to i32**
+ // get the address of %b by checking the first store that stores it
+ //CHECK: store i32 %b, i32* [[PTR_B:%.*]]
+
+ // get the size of the VLA by getting the first load of the PTR_B
+ //CHECK: [[VLA_NUM_ELEMENTS_PREZEXT:%.*]] = load i32, i32* [[PTR_B]]
+ //CHECK-NEXT: [[VLA_NUM_ELEMENTS_PRE:%.*]] = zext i32 [[VLA_NUM_ELEMENTS_PREZEXT]]
+
+ b = 15;
+ //CHECK: store i32 15, i32* [[PTR_B]]
+
+ // Now get the sizeof, and then divide by the element size
+
+
+ //CHECK: [[VLA_SIZEOF:%.*]] = mul nuw i64 4, [[VLA_NUM_ELEMENTS_PRE]]
+ //CHECK-NEXT: [[VLA_NUM_ELEMENTS_POST:%.*]] = udiv i64 [[VLA_SIZEOF]], 4
+ //CHECK-NEXT: [[VLA_END_PTR:%.*]] = getelementptr inbounds i32, i32* {{%.*}}, i64 [[VLA_NUM_ELEMENTS_POST]]
+ //X64-NEXT: store i32* [[VLA_END_PTR]], i32** %__end1
+ //AMDGCN-NEXT: store i32* [[VLA_END_PTR]], i32** [[END]]
+ for (int d : varr) 0;
+}
+
+void test3(int b, int c) {
+ // CHECK-LABEL: define void {{.*}}test3{{.*}}(i32 %b, i32 %c)
+ int varr[b][c];
+ // AMDGCN: %__end1 = alloca i32*, align 8, addrspace(5)
+ // AMDGCN: [[END:%.*]] = addrspacecast i32* addrspace(5)* %__end1 to i32**
+ // get the address of %b by checking the first store that stores it
+ //CHECK: store i32 %b, i32* [[PTR_B:%.*]]
+ //CHECK-NEXT: store i32 %c, i32* [[PTR_C:%.*]]
+
+ // get the size of the VLA by getting the first load of the PTR_B
+ //CHECK: [[VLA_DIM1_PREZEXT:%.*]] = load i32, i32* [[PTR_B]]
+ //CHECK-NEXT: [[VLA_DIM1_PRE:%.*]] = zext i32 [[VLA_DIM1_PREZEXT]]
+ //CHECK: [[VLA_DIM2_PREZEXT:%.*]] = load i32, i32* [[PTR_C]]
+ //CHECK-NEXT: [[VLA_DIM2_PRE:%.*]] = zext i32 [[VLA_DIM2_PREZEXT]]
+
+ b = 15;
+ c = 15;
+ //CHECK: store i32 15, i32* [[PTR_B]]
+ //CHECK: store i32 15, i32* [[PTR_C]]
+ // Now get the sizeof, and then divide by the element size
+
+ // multiply the two dimensions, then by the element type and then divide by the sizeof dim2
+ //CHECK: [[VLA_DIM1_X_DIM2:%.*]] = mul nuw i64 [[VLA_DIM1_PRE]], [[VLA_DIM2_PRE]]
+ //CHECK-NEXT: [[VLA_SIZEOF:%.*]] = mul nuw i64 4, [[VLA_DIM1_X_DIM2]]
+ //CHECK-NEXT: [[VLA_SIZEOF_DIM2:%.*]] = mul nuw i64 4, [[VLA_DIM2_PRE]]
+ //CHECK-NEXT: [[VLA_NUM_ELEMENTS:%.*]] = udiv i64 [[VLA_SIZEOF]], [[VLA_SIZEOF_DIM2]]
+ //CHECK-NEXT: [[VLA_END_INDEX:%.*]] = mul nsw i64 [[VLA_NUM_ELEMENTS]], [[VLA_DIM2_PRE]]
+ //CHECK-NEXT: [[VLA_END_PTR:%.*]] = getelementptr inbounds i32, i32* {{%.*}}, i64 [[VLA_END_INDEX]]
+ //X64-NEXT: store i32* [[VLA_END_PTR]], i32** %__end
+ //AMDGCN-NEXT: store i32* [[VLA_END_PTR]], i32** [[END]]
+
+ for (auto &d : varr) 0;
+}
+
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/vlt_to_reference.cpp b/src/llvm-project/clang/test/CodeGenCXX/vlt_to_reference.cpp
new file mode 100644
index 0000000..49d7f1a
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/vlt_to_reference.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+
+// CHECK-LABEL: @main
+
+struct dyn_array {
+ int size;
+ int data[];
+};
+
+int foo(dyn_array **&d) {
+ return (*d)->data[1];
+}
+
+int main()
+{
+ dyn_array **d;
+ return foo(d);
+
+ // CHECK: call {{.+}} @{{.+}}foo{{.+}}(
+ // CHECK: ret i{{[0-9]+}}
+}
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/volatile-1.cpp b/src/llvm-project/clang/test/CodeGenCXX/volatile-1.cpp
new file mode 100644
index 0000000..525e828
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/volatile-1.cpp
@@ -0,0 +1,366 @@
+// RUN: %clang_cc1 -Wno-unused-value -triple %itanium_abi_triple -emit-llvm %s -std=c++98 -o - | FileCheck %s
+// RUN: %clang_cc1 -Wno-unused-value -triple %itanium_abi_triple -emit-llvm %s -std=c++11 -o - | FileCheck -check-prefix=CHECK -check-prefix=CHECK11 %s
+
+// CHECK: @i = {{(dso_local )?}}global [[INT:i[0-9]+]] 0
+volatile int i, j, k;
+volatile int ar[5];
+volatile char c;
+// CHECK: @ci = {{(dso_local )?}}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 in C++98
+ i;
+ // CHECK11-NEXT: load volatile [[INT]], [[INT]]* @i
+
+ (float)(ci);
+ // CHECK-NEXT: load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0)
+ // CHECK-NEXT: load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
+ // CHECK-NEXT: sitofp [[INT]]
+
+ // These are not uses in C++98:
+ // [expr.static.cast]p6:
+ // The lvalue-to-rvalue . . . conversions are not applied to the expression.
+ (void)ci;
+ // CHECK11-NEXT: load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0)
+ // CHECK11-NEXT: load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
+
+ (void)a;
+
+ (void)(ci=ci);
+ // CHECK-NEXT: [[R:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0)
+ // CHECK-NEXT: [[I:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
+ // CHECK-NEXT: store volatile [[INT]] [[R]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0)
+ // CHECK-NEXT: store volatile [[INT]] [[I]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
+
+ (void)(i=j);
+ // CHECK-NEXT: [[T:%.*]] = load volatile [[INT]], [[INT]]* @j
+ // CHECK-NEXT: store volatile [[INT]] [[T]], [[INT]]* @i
+
+ ci+=ci;
+ // CHECK-NEXT: [[R1:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0)
+ // CHECK-NEXT: [[I1:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
+ // CHECK-NEXT: [[R2:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0)
+ // CHECK-NEXT: [[I2:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[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: store volatile [[INT]] [[R]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0)
+ // CHECK-NEXT: store volatile [[INT]] [[I]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
+
+ // Note that C++ requires an extra load volatile over C from the LHS of the '+'.
+ (ci += ci) + ci;
+ // CHECK-NEXT: [[R1:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0)
+ // CHECK-NEXT: [[I1:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
+ // CHECK-NEXT: [[R2:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0)
+ // CHECK-NEXT: [[I2:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
+ // CHECK-NEXT: [[R:%.*]] = add [[INT]] [[R2]], [[R1]]
+ // CHECK-NEXT: [[I:%.*]] = add [[INT]] [[I2]], [[I1]]
+ // CHECK-NEXT: store volatile [[INT]] [[R]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0)
+ // CHECK-NEXT: store volatile [[INT]] [[I]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
+ // CHECK-NEXT: [[R1:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0)
+ // CHECK-NEXT: [[I1:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
+ // CHECK-NEXT: [[R2:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0)
+ // CHECK-NEXT: [[I2:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[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 load volatile in C++.
+ (i += j) + k;
+ // CHECK-NEXT: load volatile
+ // CHECK-NEXT: load volatile
+ // CHECK-NEXT: add nsw [[INT]]
+ // CHECK-NEXT: store volatile
+ // CHECK-NEXT: load volatile
+ // CHECK-NEXT: load volatile
+ // CHECK-NEXT: add nsw [[INT]]
+
+ asm("nop"); // CHECK-NEXT: call void asm
+
+ // Extra load volatile in C++.
+ (i += j) + 1;
+ // CHECK-NEXT: load volatile
+ // CHECK-NEXT: load volatile
+ // CHECK-NEXT: add nsw [[INT]]
+ // CHECK-NEXT: store volatile
+ // CHECK-NEXT: load volatile
+ // CHECK-NEXT: add nsw [[INT]]
+
+ asm("nop"); // CHECK-NEXT: call void asm
+
+ ci+ci;
+ // CHECK-NEXT: load volatile
+ // CHECK-NEXT: load volatile
+ // CHECK-NEXT: load volatile
+ // CHECK-NEXT: load volatile
+ // CHECK-NEXT: add [[INT]]
+ // CHECK-NEXT: add [[INT]]
+
+ __real i;
+
+ +ci;
+ // CHECK-NEXT: load volatile
+ // CHECK-NEXT: load volatile
+
+ asm("nop"); // CHECK-NEXT: call void asm
+
+ (void)(i=i);
+ // CHECK-NEXT: load volatile
+ // CHECK-NEXT: store volatile
+
+ (float)(i=i);
+ // CHECK-NEXT: load volatile
+ // CHECK-NEXT: store volatile
+ // CHECK-NEXT: load volatile
+ // CHECK-NEXT: sitofp
+
+ (void)i; // This is now a load in C++11
+ // CHECK11-NEXT: load volatile
+
+ i=i;
+ // CHECK-NEXT: load volatile
+ // CHECK-NEXT: store volatile
+
+ // Extra load volatile in C++.
+ i=i=i;
+ // CHECK-NEXT: load volatile
+ // CHECK-NEXT: store volatile
+ // CHECK-NEXT: load volatile
+ // CHECK-NEXT: store volatile
+
+ (void)__builtin_choose_expr(0, i=i, j=j);
+ // CHECK-NEXT: load volatile
+ // CHECK-NEXT: store volatile
+
+ k ? (i=i) : (j=j);
+ // CHECK-NEXT: load volatile
+ // CHECK-NEXT: icmp
+ // CHECK-NEXT: br i1
+ // CHECK: load volatile
+ // CHECK-NEXT: store volatile
+ // CHECK-NEXT: br label
+ // CHECK: load volatile
+ // CHECK-NEXT: store volatile
+ // CHECK-NEXT: br label
+ // CHECK: phi
+
+ (void)(i,(i=i)); // first i is also a load in C++11
+ // CHECK11-NEXT: load volatile
+ // CHECK-NEXT: load volatile
+ // CHECK-NEXT: store volatile
+
+ i=i,k; // k is also a load in C++11
+ // CHECK-NEXT: load volatile [[INT]], [[INT]]* @i
+ // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @i
+ // CHECK11-NEXT: load volatile [[INT]], [[INT]]* @k
+
+ (i=j,k=j);
+ // CHECK-NEXT: load volatile [[INT]], [[INT]]* @j
+ // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @i
+ // CHECK-NEXT: load volatile [[INT]], [[INT]]* @j
+ // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @k
+
+ (i=j,k); // k is also a load in C++11
+ // CHECK-NEXT: load volatile [[INT]], [[INT]]* @j
+ // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @i
+ // CHECK11-NEXT: load volatile [[INT]], [[INT]]* @k
+
+ (i,j); // i and j both are loads in C++11
+ // CHECK11-NEXT: load volatile [[INT]], [[INT]]* @i
+ // CHECK11-NEXT: load volatile [[INT]], [[INT]]* @j
+
+ // Extra load in C++.
+ i=c=k;
+ // CHECK-NEXT: load volatile
+ // CHECK-NEXT: trunc
+ // CHECK-NEXT: store volatile
+ // CHECK-NEXT: load volatile
+ // CHECK-NEXT: sext
+ // CHECK-NEXT: store volatile
+
+ i+=k;
+ // CHECK-NEXT: load volatile
+ // CHECK-NEXT: load volatile
+ // CHECK-NEXT: add nsw [[INT]]
+ // CHECK-NEXT: store volatile
+
+ ci; // ci is a load in C++11
+ // CHECK11-NEXT: load volatile {{.*}} @ci, i32 0, i32 0
+ // CHECK11-NEXT: load volatile {{.*}} @ci, i32 0, i32 1
+
+ asm("nop"); // CHECK-NEXT: call void asm
+
+ (int)ci;
+ // CHECK-NEXT: load volatile {{.*}} @ci, i32 0, i32 0
+ // CHECK-NEXT: load volatile {{.*}} @ci, i32 0, i32 1
+
+ (bool)ci;
+ // CHECK-NEXT: load volatile {{.*}} @ci, i32 0, i32 0
+ // CHECK-NEXT: load volatile {{.*}} @ci, i32 0, i32 1
+ // CHECK-NEXT: icmp ne
+ // CHECK-NEXT: icmp ne
+ // CHECK-NEXT: or i1
+
+ ci=ci;
+ // CHECK-NEXT: load volatile
+ // CHECK-NEXT: load volatile
+ // CHECK-NEXT: store volatile
+ // CHECK-NEXT: store volatile
+
+ asm("nop"); // CHECK-NEXT: call void asm
+
+ // Extra load in C++.
+ ci=ci=ci;
+ // CHECK-NEXT: load volatile
+ // CHECK-NEXT: load volatile
+ // CHECK-NEXT: store volatile
+ // CHECK-NEXT: store volatile
+ // CHECK-NEXT: load volatile
+ // CHECK-NEXT: load volatile
+ // CHECK-NEXT: store volatile
+ // CHECK-NEXT: store volatile
+
+ __imag ci = __imag ci = __imag ci;
+ // CHECK-NEXT: [[T:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
+ // CHECK-NEXT: store volatile [[INT]] [[T]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
+ // CHECK-NEXT: [[T:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
+ // CHECK-NEXT: store volatile [[INT]] [[T]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1)
+
+ __real (i = j);
+ // CHECK-NEXT: load volatile
+ // CHECK-NEXT: store volatile
+
+ __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 {{.*}}void
+ ((a=a),a);
+
+ // Not a use. gcc gets this wrong, it doesn't emit the copy!
+ // CHECK-NEXT: call {{.*}}void
+ (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: load volatile
+ // CHECK-NEXT: store volatile
+
+ // C++ does an extra load here. Note that we have to do full loads.
+ (float)(ci=ci);
+ // CHECK-NEXT: load volatile
+ // CHECK-NEXT: load volatile
+ // CHECK-NEXT: store volatile
+ // CHECK-NEXT: store volatile
+ // CHECK-NEXT: load volatile
+ // CHECK-NEXT: load volatile
+ // 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: load volatile
+ // CHECK-NEXT: load volatile
+ // CHECK-NEXT: store volatile
+ // CHECK-NEXT: store volatile
+ // CHECK-NEXT: load volatile
+ // CHECK-NEXT: load volatile
+
+ // A use.
+ (float)(i=i);
+ // CHECK-NEXT: load volatile
+ // CHECK-NEXT: store volatile
+ // CHECK-NEXT: load volatile
+ // 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: load volatile
+ // CHECK-NEXT: store volatile
+ // CHECK-NEXT: load volatile
+
+ // A use.
+ -(i=j);
+ // CHECK-NEXT: load volatile
+ // CHECK-NEXT: store volatile
+ // CHECK-NEXT: load volatile
+ // 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: load volatile
+ // CHECK-NEXT: store volatile
+ // CHECK-NEXT: load volatile
+
+ // 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: load volatile
+ // CHECK-NEXT: load volatile
+ // CHECK-NEXT: store volatile
+ // CHECK-NEXT: store volatile
+
+ // A use.
+ i + 0;
+ // CHECK-NEXT: load volatile
+ // CHECK-NEXT: add
+
+ // A use.
+ (i=j) + i;
+ // CHECK-NEXT: load volatile
+ // CHECK-NEXT: store volatile
+ // CHECK-NEXT: load volatile
+ // CHECK-NEXT: load volatile
+ // 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: load volatile
+ // CHECK-NEXT: store volatile
+ // CHECK-NEXT: load volatile
+ // CHECK-NEXT: add
+
+ (i,j)=k; // i is also a load in C++11
+ // CHECK-NEXT: load volatile [[INT]], [[INT]]* @k
+ // CHECK11-NEXT: load volatile [[INT]], [[INT]]* @i
+ // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @j
+
+ (j=k,i)=i;
+ // CHECK-NEXT: load volatile [[INT]], [[INT]]* @i
+ // CHECK-NEXT: load volatile [[INT]], [[INT]]* @k
+ // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @j
+ // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @i
+
+ // CHECK-NEXT: ret void
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/volatile.cpp b/src/llvm-project/clang/test/CodeGenCXX/volatile.cpp
new file mode 100644
index 0000000..9c0271b
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/volatile.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -std=c++98 -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -std=c++11 -o - | FileCheck -check-prefix=CHECK -check-prefix=CHECK11 %s
+
+// Check that IR gen doesn't try to do an lvalue-to-rvalue conversion
+// on a volatile reference result. rdar://problem/8338198
+namespace test0 {
+ struct A {
+ A(const A& t);
+ A& operator=(const A& t);
+ volatile A& operator=(const volatile A& t) volatile;
+ };
+
+ volatile A *array;
+
+ // CHECK-LABEL: define void @_ZN5test04testENS_1AE(
+ void test(A t) {
+ // CHECK: [[ARR:%.*]] = load [[A:%.*]]*, [[A:%.*]]** @_ZN5test05arrayE, align 8
+ // CHECK-NEXT: [[IDX:%.*]] = getelementptr inbounds [[A]], [[A]]* [[ARR]], i64 0
+ // CHECK-NEXT: [[TMP:%.*]] = call dereferenceable({{[0-9]+}}) [[A]]* @_ZNV5test01AaSERVKS0_([[A]]* [[IDX]], [[A]]* dereferenceable({{[0-9]+}}) [[T:%.*]])
+ // CHECK-NEXT: ret void
+ array[0] = t;
+ }
+}
+
+namespace test1 {
+ volatile int *x;
+
+ // CHECK-LABEL: define void @_ZN5test14testEv()
+ void test() {
+ // CHECK: [[TMP:%.*]] = load i32*, i32** @_ZN5test11xE, align 8
+ // CHECK11-NEXT: {{%.*}} = load volatile i32, i32* [[TMP]], align 4
+ // CHECK-NEXT: ret void
+ *x;
+ }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/vtable-align.cpp b/src/llvm-project/clang/test/CodeGenCXX/vtable-align.cpp
new file mode 100644
index 0000000..bd0494f
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/vtable-align.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 %s -triple=i386-apple-darwin10 -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-32
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-64
+
+struct A {
+ virtual void f();
+ virtual void g();
+ virtual void h();
+};
+
+void A::f() {}
+
+// CHECK-32: @_ZTV1A = unnamed_addr constant { [5 x i8*] } { [5 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*), i8* bitcast (void (%struct.A*)* @_ZN1A1fEv to i8*), i8* bitcast (void (%struct.A*)* @_ZN1A1gEv to i8*), i8* bitcast (void (%struct.A*)* @_ZN1A1hEv to i8*)] }, align 4
+// CHECK-32: @_ZTS1A = constant [3 x i8] c"1A\00", align 1
+// CHECK-32: @_ZTI1A = constant { i8*, i8* } { i8* bitcast (i8** getelementptr inbounds (i8*, i8** @_ZTVN10__cxxabiv117__class_type_infoE, i32 2) to i8*), i8* getelementptr inbounds ([3 x i8], [3 x i8]* @_ZTS1A, i32 0, i32 0) }, align 4
+// CHECK-64: @_ZTV1A = unnamed_addr constant { [5 x i8*] } { [5 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*), i8* bitcast (void (%struct.A*)* @_ZN1A1fEv to i8*), i8* bitcast (void (%struct.A*)* @_ZN1A1gEv to i8*), i8* bitcast (void (%struct.A*)* @_ZN1A1hEv to i8*)] }, align 8
+// CHECK-64: @_ZTS1A = constant [3 x i8] c"1A\00", align 1
+// CHECK-64: @_ZTI1A = constant { i8*, i8* } { i8* bitcast (i8** getelementptr inbounds (i8*, i8** @_ZTVN10__cxxabiv117__class_type_infoE, i64 2) to i8*), i8* getelementptr inbounds ([3 x i8], [3 x i8]* @_ZTS1A, i32 0, i32 0) }, align 8
diff --git a/src/llvm-project/clang/test/CodeGenCXX/vtable-assume-load.cpp b/src/llvm-project/clang/test/CodeGenCXX/vtable-assume-load.cpp
new file mode 100644
index 0000000..d1c2350
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/vtable-assume-load.cpp
@@ -0,0 +1,313 @@
+// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o %t.ll -O1 -disable-llvm-passes -fms-extensions -fstrict-vtable-pointers
+// RUN: %clang_cc1 %s -triple i686-pc-win32 -emit-llvm -o %t.ms.ll -O1 -disable-llvm-passes -fms-extensions -fstrict-vtable-pointers
+// FIXME: Assume load should not require -fstrict-vtable-pointers
+
+// RUN: FileCheck --check-prefix=CHECK1 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK2 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK3 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK4 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK-MS --input-file=%t.ms.ll %s
+// RUN: FileCheck --check-prefix=CHECK6 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK7 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK8 --input-file=%t.ll %s
+// RUN: FileCheck --check-prefix=CHECK9 --input-file=%t.ll %s
+namespace test1 {
+
+struct A {
+ A();
+ virtual void foo();
+};
+
+struct B : A {
+ virtual void foo();
+};
+
+void g(A *a) { a->foo(); }
+
+// CHECK1-LABEL: define void @_ZN5test14fooAEv()
+// CHECK1: call void @_ZN5test11AC1Ev(%"struct.test1::A"*
+// CHECK1: %[[VTABLE:.*]] = load i8**, i8*** %{{.*}}
+// CHECK1: %[[CMP:.*]] = icmp eq i8** %[[VTABLE]], getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN5test11AE, i32 0, inrange i32 0, i32 2)
+// CHECK1: call void @llvm.assume(i1 %[[CMP]])
+// CHECK1-LABEL: {{^}}}
+
+void fooA() {
+ A a;
+ g(&a);
+}
+
+// CHECK1-LABEL: define void @_ZN5test14fooBEv()
+// CHECK1: call void @_ZN5test11BC1Ev(%"struct.test1::B"* %{{.*}})
+// CHECK1: %[[VTABLE:.*]] = load i8**, i8*** %{{.*}}
+// CHECK1: %[[CMP:.*]] = icmp eq i8** %[[VTABLE]], getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN5test11BE, i32 0, inrange i32 0, i32 2)
+// CHECK1: call void @llvm.assume(i1 %[[CMP]])
+// CHECK1-LABEL: {{^}}}
+
+void fooB() {
+ B b;
+ g(&b);
+}
+// there should not be any assumes in the ctor that calls base ctor
+// CHECK1-LABEL: define linkonce_odr void @_ZN5test11BC2Ev(%"struct.test1::B"*
+// CHECK1-NOT: @llvm.assume(
+// CHECK1-LABEL: {{^}}}
+}
+namespace test2 {
+struct A {
+ A();
+ virtual void foo();
+};
+
+struct B {
+ B();
+ virtual void bar();
+};
+
+struct C : A, B {
+ C();
+ virtual void foo();
+};
+void g(A *a) { a->foo(); }
+void h(B *b) { b->bar(); }
+
+// CHECK2-LABEL: define void @_ZN5test24testEv()
+// CHECK2: call void @_ZN5test21CC1Ev(%"struct.test2::C"*
+// CHECK2: %[[VTABLE:.*]] = load i8**, i8*** {{.*}}
+// CHECK2: %[[CMP:.*]] = icmp eq i8** %[[VTABLE]], getelementptr inbounds ({ [3 x i8*], [3 x i8*] }, { [3 x i8*], [3 x i8*] }* @_ZTVN5test21CE, i32 0, inrange i32 0, i32 2)
+// CHECK2: call void @llvm.assume(i1 %[[CMP]])
+
+// CHECK2: %[[V2:.*]] = bitcast %"struct.test2::C"* %{{.*}} to i8*
+// CHECK2: %[[ADD_PTR:.*]] = getelementptr inbounds i8, i8* %[[V2]], i64 8
+// CHECK2: %[[V3:.*]] = bitcast i8* %[[ADD_PTR]] to i8***
+// CHECK2: %[[VTABLE2:.*]] = load i8**, i8*** %[[V3]]
+// CHECK2: %[[CMP2:.*]] = icmp eq i8** %[[VTABLE2]], getelementptr inbounds ({ [3 x i8*], [3 x i8*] }, { [3 x i8*], [3 x i8*] }* @_ZTVN5test21CE, i32 0, inrange i32 1, i32 2)
+// CHECK2: call void @llvm.assume(i1 %[[CMP2]])
+
+// CHECK2: call void @_ZN5test21gEPNS_1AE(
+// CHECK2-LABEL: {{^}}}
+
+void test() {
+ C c;
+ g(&c);
+ h(&c);
+}
+}
+
+namespace test3 {
+struct A {
+ A();
+};
+
+struct B : A {
+ B();
+ virtual void foo();
+};
+
+struct C : virtual A, B {
+ C();
+ virtual void foo();
+};
+void g(B *a) { a->foo(); }
+
+// CHECK3-LABEL: define void @_ZN5test34testEv()
+// CHECK3: call void @_ZN5test31CC1Ev(%"struct.test3::C"*
+// CHECK3: %[[CMP:.*]] = icmp eq i8** %{{.*}}, getelementptr inbounds ({ [4 x i8*] }, { [4 x i8*] }* @_ZTVN5test31CE, i32 0, inrange i32 0, i32 3)
+// CHECK3: call void @llvm.assume(i1 %[[CMP]])
+// CHECK3-LABLEL: }
+void test() {
+ C c;
+ g(&c);
+}
+} // test3
+
+namespace test4 {
+struct A {
+ A();
+ virtual void foo();
+};
+
+struct B : virtual A {
+ B();
+ virtual void foo();
+};
+struct C : B {
+ C();
+ virtual void foo();
+};
+
+void g(C *c) { c->foo(); }
+
+// CHECK4-LABEL: define void @_ZN5test44testEv()
+// CHECK4: call void @_ZN5test41CC1Ev(%"struct.test4::C"*
+// CHECK4: %[[VTABLE:.*]] = load i8**, i8*** %{{.*}}
+// CHECK4: %[[CMP:.*]] = icmp eq i8** %[[VTABLE]], getelementptr inbounds ({ [5 x i8*] }, { [5 x i8*] }* @_ZTVN5test41CE, i32 0, inrange i32 0, i32 4)
+// CHECK4: call void @llvm.assume(i1 %[[CMP]]
+
+// CHECK4: %[[VTABLE2:.*]] = load i8**, i8*** %{{.*}}
+// CHECK4: %[[CMP2:.*]] = icmp eq i8** %[[VTABLE2]], getelementptr inbounds ({ [5 x i8*] }, { [5 x i8*] }* @_ZTVN5test41CE, i32 0, inrange i32 0, i32 4)
+// CHECK4: call void @llvm.assume(i1 %[[CMP2]])
+// CHECK4-LABEL: {{^}}}
+
+void test() {
+ C c;
+ g(&c);
+}
+} // test4
+
+namespace testMS {
+
+struct __declspec(novtable) S {
+ virtual void foo();
+};
+
+void g(S &s) { s.foo(); }
+
+// if struct has novtable specifier, then we can't generate assumes
+// CHECK-MS-LABEL: define dso_local void @"?test@testMS@@YAXXZ"()
+// CHECK-MS: call x86_thiscallcc %"struct.testMS::S"* @"??0S@testMS@@QAE@XZ"(
+// CHECK-MS-NOT: @llvm.assume
+// CHECK-MS-LABEL: {{^}}}
+
+void test() {
+ S s;
+ g(s);
+}
+
+} // testMS
+
+namespace test6 {
+struct A {
+ A();
+ virtual void foo();
+ virtual ~A() {}
+};
+struct B : A {
+ B();
+};
+// FIXME: Because A's vtable is external, and no virtual functions are hidden,
+// it's safe to generate assumption loads.
+// CHECK6-LABEL: define void @_ZN5test61gEv()
+// CHECK6: call void @_ZN5test61AC1Ev(
+// CHECK6-NOT: call void @llvm.assume(
+
+// We can't emit assumption loads for B, because if we would refer to vtable
+// it would refer to functions that will not be able to find (like implicit
+// inline destructor).
+
+// CHECK6-LABEL: call void @_ZN5test61BC1Ev(
+// CHECK6-NOT: call void @llvm.assume(
+// CHECK6-LABEL: {{^}}}
+void g() {
+ A *a = new A;
+ B *b = new B;
+}
+}
+
+namespace test7 {
+// Because A's key function is defined here, vtable is generated in this TU
+// CHECK7: @_ZTVN5test71AE = unnamed_addr constant
+struct A {
+ A();
+ virtual void foo();
+ virtual void bar();
+};
+void A::foo() {}
+
+// CHECK7-LABEL: define void @_ZN5test71gEv()
+// CHECK7: call void @_ZN5test71AC1Ev(
+// CHECK7: call void @llvm.assume(
+// CHECK7-LABEL: {{^}}}
+void g() {
+ A *a = new A();
+ a->bar();
+}
+}
+
+namespace test8 {
+
+struct A {
+ virtual void foo();
+ virtual void bar();
+};
+
+// CHECK8-DAG: @_ZTVN5test81BE = available_externally unnamed_addr constant
+struct B : A {
+ B();
+ void foo();
+ void bar();
+};
+
+// CHECK8-DAG: @_ZTVN5test81CE = linkonce_odr unnamed_addr constant
+struct C : A {
+ C();
+ void bar();
+ void foo() {}
+};
+inline void C::bar() {}
+
+struct D : A {
+ D();
+ void foo();
+ void inline bar();
+};
+void D::bar() {}
+
+// CHECK8-DAG: @_ZTVN5test81EE = linkonce_odr unnamed_addr constant
+struct E : A {
+ E();
+};
+
+// CHECK8-LABEL: define void @_ZN5test81bEv()
+// CHECK8: call void @llvm.assume(
+// CHECK8-LABEL: {{^}}}
+void b() {
+ B b;
+ b.bar();
+}
+
+// FIXME: C has inline virtual functions which prohibits as from generating
+// assumption loads, but because vtable is generated in this TU (key function
+// defined here) it would be correct to refer to it.
+// CHECK8-LABEL: define void @_ZN5test81cEv()
+// CHECK8-NOT: call void @llvm.assume(
+// CHECK8-LABEL: {{^}}}
+void c() {
+ C c;
+ c.bar();
+}
+
+// FIXME: We could generate assumption loads here.
+// CHECK8-LABEL: define void @_ZN5test81dEv()
+// CHECK8-NOT: call void @llvm.assume(
+// CHECK8-LABEL: {{^}}}
+void d() {
+ D d;
+ d.bar();
+}
+
+// CHECK8-LABEL: define void @_ZN5test81eEv()
+// CHECK8: call void @llvm.assume(
+// CHECK8-LABEL: {{^}}}
+void e() {
+ E e;
+ e.bar();
+}
+}
+
+namespace test9 {
+
+struct S {
+ S();
+ __attribute__((visibility("hidden"))) virtual void doStuff();
+};
+
+// CHECK9-LABEL: define void @_ZN5test94testEv()
+// CHECK9-NOT: @llvm.assume(
+// CHECK9: }
+void test() {
+ S *s = new S();
+ s->doStuff();
+ delete s;
+}
+}
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/vtable-available-externally.cpp b/src/llvm-project/clang/test/CodeGenCXX/vtable-available-externally.cpp
new file mode 100644
index 0000000..24c2eac
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/vtable-available-externally.cpp
@@ -0,0 +1,548 @@
+// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -emit-llvm -o %t
+// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -O2 -disable-llvm-passes -emit-llvm -o %t.opt
+// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -O2 -disable-llvm-passes -emit-llvm -o %t.vtable -fforce-emit-vtables -fstrict-vtable-pointers -mconstructor-aliases
+// RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST1 %s < %t
+// RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST2 %s < %t
+// RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST5 %s < %t
+// RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST8 %s < %t.opt
+// RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST9 %s < %t.opt
+// RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST10 %s < %t.opt
+// RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST11 %s < %t.opt
+// RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST12 %s < %t.opt
+// RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST13 %s < %t.opt
+// RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST14 %s < %t.opt
+// RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST15 %s < %t.opt
+// RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST16 %s < %t.opt
+// RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST17 %s < %t.opt
+// RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-FORCE-EMIT %s < %t.vtable
+
+
+#include <typeinfo>
+
+// CHECK-TEST1: @_ZTVN5Test11AE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN5Test11AE = available_externally unnamed_addr constant
+namespace Test1 {
+
+struct A {
+ A();
+ virtual void f();
+ virtual ~A() { }
+};
+
+A::A() { }
+
+void f(A* a) {
+ a->f();
+};
+
+// CHECK-LABEL: 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 = 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-LABEL: 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 ();
+};
+}
+
+namespace Test8 {
+// CHECK-TEST8: @_ZTVN5Test81YE = available_externally unnamed_addr constant
+// vtable for X is not generated because there are no stores here
+struct X {
+ X();
+ virtual void foo();
+};
+struct Y : X {
+ void foo();
+};
+
+void g(X* p) { p->foo(); }
+void f() {
+ Y y;
+ g(&y);
+ X x;
+ g(&x);
+}
+
+} // Test8
+
+namespace Test9 {
+// All virtual functions are outline, so we can assume that it will
+// be generated in translation unit where foo is defined.
+// CHECK-TEST9-DAG: @_ZTVN5Test91AE = available_externally unnamed_addr constant
+// CHECK-TEST9-DAG: @_ZTVN5Test91BE = available_externally unnamed_addr constant
+struct A {
+ virtual void foo();
+ virtual void bar();
+};
+void A::bar() {}
+
+struct B : A {
+ void foo();
+};
+
+void g() {
+ A a;
+ a.foo();
+ B b;
+ b.foo();
+}
+
+} // Test9
+
+namespace Test10 {
+
+// because A's key function is defined here, vtable is generated in this TU
+// CHECK-TEST10-DAG: @_ZTVN6Test101AE = unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101AE = unnamed_addr constant
+struct A {
+ virtual void foo();
+ virtual void bar();
+};
+void A::foo() {}
+
+// Because key function is inline we will generate vtable as linkonce_odr.
+// CHECK-TEST10-DAG: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant
+struct D : A {
+ void bar();
+};
+inline void D::bar() {}
+
+// Because B has outline all virtual functions, we can refer to them.
+// CHECK-TEST10-DAG: @_ZTVN6Test101BE = available_externally unnamed_addr constant
+struct B : A {
+ void foo();
+ void bar();
+};
+
+// C's key function (car) is outline, but C has inline virtual function so we
+// can't guarantee that we will be able to refer to bar from name
+// so (at the moment) we can't emit vtable available_externally.
+// CHECK-TEST10-DAG: @_ZTVN6Test101CE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101CE = available_externally unnamed_addr constant
+struct C : A {
+ void bar() {} // defined in body - not key function
+ virtual inline void gar(); // inline in body - not key function
+ virtual void car();
+};
+
+// no key function, vtable will be generated everywhere it will be used
+// CHECK-TEST10-DAG: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant
+
+struct E : A {};
+
+void g(A& a) {
+ a.foo();
+ a.bar();
+}
+
+void f() {
+ A a;
+ g(a);
+ B b;
+ g(b);
+ C c;
+ g(c);
+ D d;
+ g(d);
+ E e;
+ g(e);
+}
+
+} // Test10
+
+namespace Test11 {
+struct D;
+// Can emit C's vtable available_externally.
+// CHECK-TEST11: @_ZTVN6Test111CE = available_externally unnamed_addr constant
+struct C {
+ virtual D& operator=(const D&);
+};
+
+// Can emit D's vtable available_externally.
+// CHECK-TEST11: @_ZTVN6Test111DE = available_externally unnamed_addr constant
+struct D : C {
+ virtual void key();
+};
+D f();
+
+void g(D& a) {
+ C c;
+ c = a;
+ a.key();
+ a.key();
+}
+void g() {
+ D d;
+ d = f();
+ g(d);
+}
+} // Test 11
+
+namespace Test12 {
+
+// CHECK-TEST12: @_ZTVN6Test121AE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test121AE = available_externally unnamed_addr constant
+struct A {
+ virtual void foo();
+ virtual ~A() {}
+};
+// CHECK-TEST12: @_ZTVN6Test121BE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test121BE = available_externally unnamed_addr constant
+struct B : A {
+ void foo();
+};
+
+void g() {
+ A a;
+ a.foo();
+ B b;
+ b.foo();
+}
+}
+
+namespace Test13 {
+
+// CHECK-TEST13-DAG: @_ZTVN6Test131AE = available_externally unnamed_addr constant
+// CHECK-TEST13-DAG: @_ZTVN6Test131BE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test131AE = available_externally unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test131BE = available_externally unnamed_addr constant
+
+struct A {
+ virtual ~A();
+};
+struct B : A {
+ virtual void f();
+ void operator delete(void *);
+ ~B() {}
+};
+
+void g() {
+ A *b = new B;
+}
+}
+
+namespace Test14 {
+
+// CHECK-TEST14: @_ZTVN6Test141AE = available_externally unnamed_addr constant
+struct A {
+ virtual void f();
+ void operator delete(void *);
+ ~A();
+};
+
+void g() {
+ A *b = new A;
+ delete b;
+}
+}
+
+namespace Test15 {
+// In this test D's vtable has two slots for function f(), but uses only one,
+// so the second slot is set to null.
+// CHECK-TEST15: @_ZTVN6Test151DE = available_externally unnamed_addr constant
+struct A { virtual void f() {} };
+struct B : virtual A {};
+struct C : virtual A {};
+struct D : B, C {
+ virtual void g();
+ void f();
+};
+
+void test() {
+ D * d = new D;
+ d->f();
+}
+}
+
+namespace Test16 {
+// S has virtual method that is hidden, because of it we can't
+// generate available_externally vtable for it.
+// CHECK-TEST16-DAG: @_ZTVN6Test161SE = external unnamed_addr constant
+// CHECK-TEST16-DAG: @_ZTVN6Test162S2E = available_externally
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test161SE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test162S2E = available_externally
+
+struct S {
+ __attribute__((visibility("hidden"))) virtual void doStuff();
+};
+
+struct S2 {
+ virtual void doStuff();
+ __attribute__((visibility("hidden"))) void unused();
+
+};
+
+void test() {
+ S *s = new S;
+ s->doStuff();
+
+ S2 *s2 = new S2;
+ s2->doStuff();
+}
+}
+
+namespace Test17 {
+// This test checks if we emit vtables opportunistically.
+// CHECK-TEST17-DAG: @_ZTVN6Test171AE = available_externally
+// CHECK-TEST17-DAG: @_ZTVN6Test171BE = external
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test171AE = available_externally
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test171BE = available_externally
+// CHECK-FORCE-EMIT-DAG: define linkonce_odr void @_ZN6Test171BD2Ev(
+// CHECK-FORCE-EMIT-DAG: define linkonce_odr void @_ZN6Test171BD0Ev(
+
+struct A {
+ virtual void key();
+ virtual void bar() {}
+};
+
+// We won't gonna use deleting destructor for this type, which will disallow
+// emitting vtable as available_externally
+struct B {
+ virtual void key();
+ virtual ~B() {}
+};
+
+void testcaseA() {
+ A a;
+ a.bar(); // this forces to emit definition of bar
+}
+
+void testcaseB() {
+ B b; // This only forces emitting of complete object destructor
+}
+
+} // namespace Test17
+
+namespace Test18 {
+// Here vtable will be only emitted because it is referenced by assume-load
+// after the Derived construction.
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test187DerivedE = linkonce_odr unnamed_addr constant {{.*}} @_ZTIN6Test187DerivedE {{.*}} @_ZN6Test184Base3funEv {{.*}} @_ZN6Test184BaseD2Ev {{.*}} @_ZN6Test187DerivedD0Ev
+// CHECK-FORCE-EMIT-DAG: define linkonce_odr void @_ZN6Test187DerivedD0Ev
+// CHECK-FORCE-EMIT-DAG: define linkonce_odr void @_ZN6Test184BaseD2Ev
+// CHECK-FORCE-EMIT-DAG: define linkonce_odr i32 @_ZN6Test184Base3funEv
+// CHECK-FORCE-EMIT-DAG: @_ZTIN6Test187DerivedE = linkonce_odr constant
+
+struct Base {
+ virtual int fun() { return 42; }
+ virtual ~Base() { }
+};
+
+struct Derived : Base {
+ Derived();
+};
+
+int foo() {
+ Derived *der = new Derived();
+ return der->fun();
+}
+}
+
+namespace TestTemplates {
+
+// CHECK-FORCE-EMIT-DAG: @_ZTVN13TestTemplates8TemplateIiEE = linkonce_odr unnamed_addr constant {{.*}} @_ZTIN13TestTemplates8TemplateIiEE {{.*}} @_ZN13TestTemplates8TemplateIiE3fooEi {{.*}}@_ZN13TestTemplates8TemplateIiE22thisShouldBeEmittedTooEi {{.*}}@_ZN13TestTemplates8TemplateIiED1Ev {{.*}}@_ZN13TestTemplates8TemplateIiED0Ev
+// CHECK-FORCE-EMIT-DAG: define linkonce_odr i32 @_ZN13TestTemplates8TemplateIiE22thisShouldBeEmittedTooEi
+
+template<class T>
+struct Template {
+ Template();
+ virtual T foo(T val);
+ // CHECK-FORCE-EMIT-DAG: define linkonce_odr i32 @_ZN13TestTemplates8TemplateIiE22thisShouldBeEmittedTooEi
+ virtual T thisShouldBeEmittedToo(T val) { return val; }
+ virtual ~Template();
+};
+
+
+struct NonTemplate {
+ typedef int T;
+ NonTemplate();
+ virtual T foo(T val);
+ // CHECK-FORCE-EMIT-DAG: define linkonce_odr i32 @_ZN13TestTemplates11NonTemplate22thisShouldBeEmittedTooEi
+ virtual T thisShouldBeEmittedToo(T val) { return val; }
+ virtual ~NonTemplate();
+};
+
+// CHECK-FORCE-EMIT-DAG: @_ZTVN13TestTemplates16OuterNonTemplate27NestedTemplateInNonTemplateIiEE = linkonce_odr {{.*}} @_ZTIN13TestTemplates16OuterNonTemplate27NestedTemplateInNonTemplateIiEE {{.*}} @_ZN13TestTemplates16OuterNonTemplate27NestedTemplateInNonTemplateIiE3fooEi {{.*}} @_ZN13TestTemplates16OuterNonTemplate27NestedTemplateInNonTemplateIiE22thisShouldBeEmittedTooEi {{.*}} @_ZN13TestTemplates16OuterNonTemplate27NestedTemplateInNonTemplateIiED1Ev {{.*}} @_ZN13TestTemplates16OuterNonTemplate27NestedTemplateInNonTemplateIiED0Ev
+
+struct OuterNonTemplate {
+ template<class T>
+ struct NestedTemplateInNonTemplate {
+ NestedTemplateInNonTemplate();
+ virtual T foo(T val);
+ // CHECK-FORCE-EMIT-DAG: define linkonce_odr i32 @_ZN13TestTemplates16OuterNonTemplate27NestedTemplateInNonTemplateIiE22thisShouldBeEmittedTooEi
+ virtual T thisShouldBeEmittedToo(T val) { return val; }
+ virtual ~NestedTemplateInNonTemplate();
+ };
+
+ struct NestedNonTemplateInNonTemplate {
+ typedef int T;
+ NestedNonTemplateInNonTemplate();
+ virtual T foo(T val);
+ // CHECK-FORCE-EMIT-DAG: define linkonce_odr i32 @_ZN13TestTemplates16OuterNonTemplate30NestedNonTemplateInNonTemplate22thisShouldBeEmittedTooEi
+ virtual T thisShouldBeEmittedToo(T val) { return val; }
+ virtual ~NestedNonTemplateInNonTemplate();
+ };
+};
+
+template<class>
+struct OuterTemplate {
+ template<class T>
+ struct NestedTemplateInTemplate {
+ NestedTemplateInTemplate();
+ virtual T foo(T val);
+ // CHECK-FORCE-EMIT-DAG: define linkonce_odr i32 @_ZN13TestTemplates13OuterTemplateIlE24NestedTemplateInTemplateIiE22thisShouldBeEmittedTooEi
+ virtual T thisShouldBeEmittedToo(T val) { return val; }
+ virtual ~NestedTemplateInTemplate();
+ };
+
+ struct NestedNonTemplateInTemplate {
+ typedef int T;
+ NestedNonTemplateInTemplate();
+ virtual T foo(T val);
+ // CHECK-FORCE-EMIT-DAG: define linkonce_odr i32 @_ZN13TestTemplates13OuterTemplateIlE27NestedNonTemplateInTemplate22thisShouldBeEmittedTooEi
+ virtual T thisShouldBeEmittedToo(T val) { return val; }
+ virtual ~NestedNonTemplateInTemplate();
+ };
+};
+
+template<class T>
+int use() {
+ T *ptr = new T();
+ return ptr->foo(42);
+}
+
+void test() {
+ use<Template<int> >();
+ use<OuterTemplate<long>::NestedTemplateInTemplate<int> >();
+ use<OuterNonTemplate::NestedTemplateInNonTemplate<int> >();
+
+ use<NonTemplate>();
+ use<OuterTemplate<long>::NestedNonTemplateInTemplate>();
+ use<OuterNonTemplate::NestedNonTemplateInNonTemplate>();
+}
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/vtable-cast-crash.cpp b/src/llvm-project/clang/test/CodeGenCXX/vtable-cast-crash.cpp
new file mode 100644
index 0000000..58f9e0b
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/vtable-cast-crash.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -emit-llvm-only -triple %itanium_abi_triple %s
+struct A
+{
+A();
+virtual ~A();
+};
+
+struct B: A
+{
+ B();
+ ~B();
+};
+
+B::B()
+{
+}
+
+B::~B()
+{
+}
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/vtable-debug-info.cpp b/src/llvm-project/clang/test/CodeGenCXX/vtable-debug-info.cpp
new file mode 100644
index 0000000..0ac90b3
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/vtable-debug-info.cpp
@@ -0,0 +1,319 @@
+// RUN: %clang -emit-llvm -S -g %s -o /dev/null
+// Radar 8730409
+// XFAIL: windows-msvc
+
+// FIXME: This test crashes on *-pc-win32
+// for lack of debugging support on -integrated-as (MCCOFF).
+#ifdef _MSC_VER
+
+#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/src/llvm-project/clang/test/CodeGenCXX/vtable-holder-self-reference.cpp b/src/llvm-project/clang/test/CodeGenCXX/vtable-holder-self-reference.cpp
new file mode 100644
index 0000000..727de7a
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/vtable-holder-self-reference.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -emit-llvm -dwarf-version=2 -debug-info-kind=limited -x c++ -o - %s | FileCheck %s
+//
+// PR21941: crasher for self-referencing DW_TAG_structure_type node. If we get
+// rid of self-referenceing structure_types (PR21902), then it should be safe
+// to just kill this test.
+//
+// CHECK: ![[SELF:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "B",
+// CHECK-SAME: vtableHolder: ![[SELF]]
+
+void foo() {
+ struct V {
+ int vi;
+ };
+ struct B : virtual V {};
+ B b;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/vtable-key-function-arm.cpp b/src/llvm-project/clang/test/CodeGenCXX/vtable-key-function-arm.cpp
new file mode 100644
index 0000000..3d5c3c3
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/vtable-key-function-arm.cpp
@@ -0,0 +1,307 @@
+// RUN: %clang_cc1 %s -triple=armv7-unknown-unknown -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=armv7-unknown-unknown -emit-llvm -o - | FileCheck -check-prefix=CHECK-LATE %s
+
+// The 'a' variants ask for the vtable first.
+// The 'b' variants ask for the vtable second.
+// The 'c' variants ask for the vtable third.
+// We do a separate CHECK-LATE pass because the RTTI definition gets
+// changed after the fact, which causes reordering of the globals.
+
+// These are not separated into namespaces because the way that Sema
+// currently reports namespaces to IR-generation (i.e., en masse for
+// the entire namespace at once) subverts the ordering that we're
+// trying to test.
+
+namespace std { class type_info; }
+extern void use(const std::type_info &rtti);
+
+/*** Test0a ******************************************************************/
+
+struct Test0a {
+ Test0a();
+ virtual inline void foo();
+ virtual void bar();
+};
+
+// V-table should be defined externally.
+Test0a::Test0a() { use(typeid(Test0a)); }
+// CHECK: @_ZTV6Test0a = external unnamed_addr constant
+// CHECK: @_ZTI6Test0a = external constant
+
+// This is still not a key function.
+void Test0a::foo() {}
+
+/*** Test0b ******************************************************************/
+
+struct Test0b {
+ Test0b();
+ virtual inline void foo();
+ virtual void bar();
+};
+
+// This is still not a key function.
+void Test0b::foo() {}
+
+// V-table should be defined externally.
+Test0b::Test0b() { use(typeid(Test0b)); }
+// CHECK: @_ZTV6Test0b = external unnamed_addr constant
+// CHECK: @_ZTI6Test0b = external constant
+
+/*** Test1a ******************************************************************/
+
+struct Test1a {
+ Test1a();
+ virtual void foo();
+ virtual void bar();
+};
+
+// V-table should be defined externally.
+Test1a::Test1a() { use(typeid(Test1a)); }
+// CHECK: @_ZTV6Test1a = external unnamed_addr constant
+// CHECK: @_ZTI6Test1a = external constant
+
+// 'bar' becomes the key function when 'foo' is defined inline.
+inline void Test1a::foo() {}
+
+/*** Test1b ******************************************************************/
+
+struct Test1b {
+ Test1b();
+ virtual void foo();
+ virtual void bar();
+};
+
+// 'bar' becomes the key function when 'foo' is defined inline.
+inline void Test1b::foo() {}
+
+// V-table should be defined externally.
+Test1b::Test1b() { use(typeid(Test1b)); }
+// CHECK: @_ZTV6Test1b = external unnamed_addr constant
+// CHECK: @_ZTI6Test1b = external constant
+
+/*** Test2a ******************************************************************/
+
+struct Test2a {
+ Test2a();
+ virtual void foo();
+ virtual void bar();
+};
+
+// V-table should be defined with strong linkage.
+Test2a::Test2a() { use(typeid(Test2a)); }
+// CHECK: @_ZTV6Test2a = unnamed_addr constant
+// CHECK-LATE: @_ZTS6Test2a = constant
+// CHECK-LATE: @_ZTI6Test2a = constant
+
+// 'bar' becomes the key function when 'foo' is defined inline.
+void Test2a::bar() {}
+inline void Test2a::foo() {}
+
+/*** Test2b ******************************************************************/
+
+struct Test2b {
+ Test2b();
+ virtual void foo();
+ virtual void bar();
+};
+
+// 'bar' becomes the key function when 'foo' is defined inline.
+void Test2b::bar() {}
+
+// V-table should be defined with strong linkage.
+Test2b::Test2b() { use(typeid(Test2b)); }
+// CHECK: @_ZTV6Test2b = unnamed_addr constant
+// CHECK-LATE: @_ZTS6Test2b = constant
+// CHECK-LATE: @_ZTI6Test2b = constant
+
+inline void Test2b::foo() {}
+
+/*** Test2c ******************************************************************/
+
+struct Test2c {
+ Test2c();
+ virtual void foo();
+ virtual void bar();
+};
+
+// 'bar' becomes the key function when 'foo' is defined inline.
+void Test2c::bar() {}
+inline void Test2c::foo() {}
+
+// V-table should be defined with strong linkage.
+Test2c::Test2c() { use(typeid(Test2c)); }
+// CHECK: @_ZTV6Test2c = unnamed_addr constant
+// CHECK: @_ZTS6Test2c = constant
+// CHECK: @_ZTI6Test2c = constant
+
+/*** Test3a ******************************************************************/
+
+struct Test3a {
+ Test3a();
+ virtual void foo();
+ virtual void bar();
+};
+
+// V-table should be defined with weak linkage.
+Test3a::Test3a() { use(typeid(Test3a)); }
+// CHECK: @_ZTV6Test3a = linkonce_odr unnamed_addr constant
+// CHECK-LATE: @_ZTS6Test3a = linkonce_odr constant
+// CHECK-LATE: @_ZTI6Test3a = linkonce_odr constant
+
+// There ceases to be a key function after these declarations.
+inline void Test3a::bar() {}
+inline void Test3a::foo() {}
+
+/*** Test3b ******************************************************************/
+
+struct Test3b {
+ Test3b();
+ virtual void foo();
+ virtual void bar();
+};
+
+// There ceases to be a key function after these declarations.
+inline void Test3b::bar() {}
+
+// V-table should be defined with weak linkage.
+Test3b::Test3b() { use(typeid(Test3b)); }
+// CHECK: @_ZTV6Test3b = linkonce_odr unnamed_addr constant
+// CHECK-LATE: @_ZTS6Test3b = linkonce_odr constant
+// CHECK-LATE: @_ZTI6Test3b = linkonce_odr constant
+
+inline void Test3b::foo() {}
+
+/*** Test3c ******************************************************************/
+
+struct Test3c {
+ Test3c();
+ virtual void foo();
+ virtual void bar();
+};
+
+// There ceases to be a key function after these declarations.
+inline void Test3c::bar() {}
+inline void Test3c::foo() {}
+
+// V-table should be defined with weak linkage.
+Test3c::Test3c() { use(typeid(Test3c)); }
+// CHECK: @_ZTV6Test3c = linkonce_odr unnamed_addr constant
+// CHECK: @_ZTS6Test3c = linkonce_odr constant
+// CHECK: @_ZTI6Test3c = linkonce_odr constant
+
+/*** Test4a ******************************************************************/
+
+template <class T> struct Test4a {
+ Test4a();
+ virtual void foo();
+ virtual void bar();
+};
+
+// V-table should be defined with weak linkage.
+template <> Test4a<int>::Test4a() { use(typeid(Test4a)); }
+// CHECK: @_ZTV6Test4aIiE = linkonce_odr unnamed_addr constant
+// CHECK: @_ZTS6Test4aIiE = linkonce_odr constant
+// CHECK: @_ZTI6Test4aIiE = linkonce_odr constant
+
+// There ceases to be a key function after these declarations.
+template <> inline void Test4a<int>::bar() {}
+template <> inline void Test4a<int>::foo() {}
+
+/*** Test4b ******************************************************************/
+
+template <class T> struct Test4b {
+ Test4b();
+ virtual void foo();
+ virtual void bar();
+};
+
+// There ceases to be a key function after these declarations.
+template <> inline void Test4b<int>::bar() {}
+
+// V-table should be defined with weak linkage.
+template <> Test4b<int>::Test4b() { use(typeid(Test4b)); }
+// CHECK: @_ZTV6Test4bIiE = linkonce_odr unnamed_addr constant
+// CHECK: @_ZTS6Test4bIiE = linkonce_odr constant
+// CHECK: @_ZTI6Test4bIiE = linkonce_odr constant
+
+template <> inline void Test4b<int>::foo() {}
+
+/*** Test4c ******************************************************************/
+
+template <class T> struct Test4c {
+ Test4c();
+ virtual void foo();
+ virtual void bar();
+};
+
+// There ceases to be a key function after these declarations.
+template <> inline void Test4c<int>::bar() {}
+template <> inline void Test4c<int>::foo() {}
+
+// V-table should be defined with weak linkage.
+template <> Test4c<int>::Test4c() { use(typeid(Test4c)); }
+// CHECK: @_ZTV6Test4cIiE = linkonce_odr unnamed_addr constant
+// CHECK: @_ZTS6Test4cIiE = linkonce_odr constant
+// CHECK: @_ZTI6Test4cIiE = linkonce_odr constant
+
+/*** Test5a ******************************************************************/
+
+template <class T> struct Test5a {
+ Test5a();
+ virtual void foo();
+ virtual void bar();
+};
+
+template <> inline void Test5a<int>::bar();
+template <> inline void Test5a<int>::foo();
+
+// V-table should be defined with weak linkage.
+template <> Test5a<int>::Test5a() { use(typeid(Test5a)); }
+// CHECK: @_ZTV6Test5aIiE = linkonce_odr unnamed_addr constant
+// CHECK: @_ZTS6Test5aIiE = linkonce_odr constant
+// CHECK: @_ZTI6Test5aIiE = linkonce_odr constant
+
+// There ceases to be a key function after these declarations.
+template <> inline void Test5a<int>::bar() {}
+template <> inline void Test5a<int>::foo() {}
+
+/*** Test5b ******************************************************************/
+
+template <class T> struct Test5b {
+ Test5b();
+ virtual void foo();
+ virtual void bar();
+};
+
+// There ceases to be a key function after these declarations.
+template <> inline void Test5a<int>::bar();
+template <> inline void Test5b<int>::bar() {}
+
+// V-table should be defined with weak linkage.
+template <> Test5b<int>::Test5b() { use(typeid(Test5b)); }
+// CHECK: @_ZTV6Test5bIiE = linkonce_odr unnamed_addr constant
+// CHECK: @_ZTS6Test5bIiE = linkonce_odr constant
+// CHECK: @_ZTI6Test5bIiE = linkonce_odr constant
+
+template <> inline void Test5a<int>::foo();
+template <> inline void Test5b<int>::foo() {}
+
+/*** Test5c ******************************************************************/
+
+template <class T> struct Test5c {
+ Test5c();
+ virtual void foo();
+ virtual void bar();
+};
+
+// There ceases to be a key function after these declarations.
+template <> inline void Test5a<int>::bar();
+template <> inline void Test5a<int>::foo();
+template <> inline void Test5c<int>::bar() {}
+template <> inline void Test5c<int>::foo() {}
+
+// V-table should be defined with weak linkage.
+template <> Test5c<int>::Test5c() { use(typeid(Test5c)); }
+// CHECK: @_ZTV6Test5cIiE = linkonce_odr unnamed_addr constant
+// CHECK: @_ZTS6Test5cIiE = linkonce_odr constant
+// CHECK: @_ZTI6Test5cIiE = linkonce_odr constant
diff --git a/src/llvm-project/clang/test/CodeGenCXX/vtable-key-function-ios.cpp b/src/llvm-project/clang/test/CodeGenCXX/vtable-key-function-ios.cpp
new file mode 100644
index 0000000..a119c78
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/vtable-key-function-ios.cpp
@@ -0,0 +1,192 @@
+// RUN: %clang_cc1 %s -triple=armv7-apple-darwin -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=armv7-apple-darwin -emit-llvm -o - | FileCheck -check-prefix=CHECK-LATE %s
+
+// RUN: %clang_cc1 %s -triple=x86_64-pc-windows-gnu -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=x86_64-pc-windows-gnu -emit-llvm -o - | FileCheck -check-prefix=CHECK-LATE %s
+
+// The 'a' variants ask for the vtable first.
+// The 'b' variants ask for the vtable second.
+// The 'c' variants ask for the vtable third.
+// We do a separate CHECK-LATE pass because the RTTI definition gets
+// changed after the fact, which causes reordering of the globals.
+
+// These are not separated into namespaces because the way that Sema
+// currently reports namespaces to IR-generation (i.e., en masse for
+// the entire namespace at once) subverts the ordering that we're
+// trying to test.
+
+namespace std { class type_info; }
+extern void use(const std::type_info &rtti);
+
+/*** Test0a ******************************************************************/
+
+struct Test0a {
+ Test0a();
+ virtual inline void foo();
+ virtual void bar();
+};
+
+// V-table should be defined externally.
+Test0a::Test0a() { use(typeid(Test0a)); }
+// CHECK: @_ZTV6Test0a = external {{(dso_local )?}}unnamed_addr constant
+// CHECK: @_ZTI6Test0a = external {{(dso_local )?}}constant
+
+// This is not a key function.
+void Test0a::foo() {}
+
+/*** Test0b ******************************************************************/
+
+struct Test0b {
+ Test0b();
+ virtual inline void foo();
+ virtual void bar();
+};
+
+// This is not a key function.
+void Test0b::foo() {}
+
+// V-table should be defined externally.
+Test0b::Test0b() { use(typeid(Test0b)); }
+// CHECK: @_ZTV6Test0b = external {{(dso_local )?}}unnamed_addr constant
+// CHECK: @_ZTI6Test0b = external {{(dso_local )?}}constant
+
+/*** Test1a ******************************************************************/
+
+struct Test1a {
+ Test1a();
+ virtual void foo();
+ virtual void bar();
+};
+
+// V-table needs to be defined weakly.
+Test1a::Test1a() { use(typeid(Test1a)); }
+// CHECK: @_ZTV6Test1a = linkonce_odr {{(dso_local )?}}unnamed_addr constant
+// CHECK-LATE: @_ZTS6Test1a = linkonce_odr {{(dso_local )?}}constant
+// CHECK-LATE: @_ZTI6Test1a = linkonce_odr {{(dso_local )?}}constant
+
+// This defines the key function.
+inline void Test1a::foo() {}
+
+/*** Test1b ******************************************************************/
+
+struct Test1b {
+ Test1b();
+ virtual void foo();
+ virtual void bar();
+};
+
+// This defines the key function.
+inline void Test1b::foo() {}
+
+// V-table should be defined weakly..
+Test1b::Test1b() { use(typeid(Test1b)); }
+// CHECK: @_ZTV6Test1b = linkonce_odr {{(dso_local )?}}unnamed_addr constant
+// CHECK: @_ZTS6Test1b = linkonce_odr {{(dso_local )?}}constant
+// CHECK: @_ZTI6Test1b = linkonce_odr {{(dso_local )?}}constant
+
+/*** Test2a ******************************************************************/
+
+struct Test2a {
+ Test2a();
+ virtual void foo();
+ virtual void bar();
+};
+
+// V-table should be defined with weak linkage.
+Test2a::Test2a() { use(typeid(Test2a)); }
+// CHECK: @_ZTV6Test2a = linkonce_odr {{(dso_local )?}}unnamed_addr constant
+// CHECK-LATE: @_ZTS6Test2a = linkonce_odr {{(dso_local )?}}constant
+// CHECK-LATE: @_ZTI6Test2a = linkonce_odr {{(dso_local )?}}constant
+
+void Test2a::bar() {}
+inline void Test2a::foo() {}
+
+/*** Test2b ******************************************************************/
+
+struct Test2b {
+ Test2b();
+ virtual void foo();
+ virtual void bar();
+};
+
+void Test2b::bar() {}
+
+// V-table should be defined with weak linkage.
+Test2b::Test2b() { use(typeid(Test2b)); }
+// CHECK: @_ZTV6Test2b = linkonce_odr {{(dso_local )?}}unnamed_addr constant
+// CHECK-LATE: @_ZTS6Test2b = linkonce_odr {{(dso_local )?}}constant
+// CHECK-LATE: @_ZTI6Test2b = linkonce_odr {{(dso_local )?}}constant
+
+inline void Test2b::foo() {}
+
+/*** Test2c ******************************************************************/
+
+struct Test2c {
+ Test2c();
+ virtual void foo();
+ virtual void bar();
+};
+
+void Test2c::bar() {}
+inline void Test2c::foo() {}
+
+// V-table should be defined with weak linkage.
+Test2c::Test2c() { use(typeid(Test2c)); }
+// CHECK: @_ZTV6Test2c = linkonce_odr {{(dso_local )?}}unnamed_addr constant
+// CHECK: @_ZTS6Test2c = linkonce_odr {{(dso_local )?}}constant
+// CHECK: @_ZTI6Test2c = linkonce_odr {{(dso_local )?}}constant
+
+/*** Test3a ******************************************************************/
+
+struct Test3a {
+ Test3a();
+ virtual void foo();
+ virtual void bar();
+};
+
+// V-table should be defined with weak linkage.
+Test3a::Test3a() { use(typeid(Test3a)); }
+// CHECK: @_ZTV6Test3a = linkonce_odr {{(dso_local )?}}unnamed_addr constant
+// CHECK-LATE: @_ZTS6Test3a = linkonce_odr {{(dso_local )?}}constant
+// CHECK-LATE: @_ZTI6Test3a = linkonce_odr {{(dso_local )?}}constant
+
+// This defines the key function.
+inline void Test3a::bar() {}
+inline void Test3a::foo() {}
+
+/*** Test3b ******************************************************************/
+
+struct Test3b {
+ Test3b();
+ virtual void foo();
+ virtual void bar();
+};
+
+inline void Test3b::bar() {}
+
+// V-table should be defined with weak linkage.
+Test3b::Test3b() { use(typeid(Test3b)); }
+// CHECK: @_ZTV6Test3b = linkonce_odr {{(dso_local )?}}unnamed_addr constant
+// CHECK-LATE: @_ZTS6Test3b = linkonce_odr {{(dso_local )?}}constant
+// CHECK-LATE: @_ZTI6Test3b = linkonce_odr {{(dso_local )?}}constant
+
+// This defines the key function.
+inline void Test3b::foo() {}
+
+/*** Test3c ******************************************************************/
+
+struct Test3c {
+ Test3c();
+ virtual void foo();
+ virtual void bar();
+};
+
+// This defines the key function.
+inline void Test3c::bar() {}
+inline void Test3c::foo() {}
+
+// V-table should be defined with weak linkage.
+Test3c::Test3c() { use(typeid(Test3c)); }
+// CHECK: @_ZTV6Test3c = linkonce_odr {{(dso_local )?}}unnamed_addr constant
+// CHECK: @_ZTS6Test3c = linkonce_odr {{(dso_local )?}}constant
+// CHECK: @_ZTI6Test3c = linkonce_odr {{(dso_local )?}}constant
diff --git a/src/llvm-project/clang/test/CodeGenCXX/vtable-key-function-win-comdat.cpp b/src/llvm-project/clang/test/CodeGenCXX/vtable-key-function-win-comdat.cpp
new file mode 100644
index 0000000..e7c5be9
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/vtable-key-function-win-comdat.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 %s -triple=x86_64-pc-windows-gnu -emit-llvm -o - | FileCheck %s
+
+namespace std { class type_info; }
+extern void use(const std::type_info &rtti);
+
+struct Test1a {
+ Test1a();
+ virtual void foo();
+ virtual void bar();
+};
+
+// V-table needs to be defined weakly.
+Test1a::Test1a() { use(typeid(Test1a)); }
+// This defines the key function.
+inline void Test1a::foo() {}
+
+// CHECK: $_ZTV6Test1a = comdat any
+// CHECK: $_ZTS6Test1a = comdat any
+// CHECK: $_ZTI6Test1a = comdat any
+// CHECK-NOT: $_ZTS6Test1a.1 = comdat any
+// CHECK-NOT: $_ZTI6Test1a.1 = comdat any
+
+// CHECK: @_ZTV6Test1a = linkonce_odr dso_local unnamed_addr constant {{.*}} ({ i8*, i8* }* @_ZTI6Test1a to i8*)
+// CHECK: @_ZTS6Test1a = linkonce_odr dso_local constant
+// CHECK: @_ZTI6Test1a = linkonce_odr dso_local constant {{.*}} [8 x i8]* @_ZTS6Test1a
diff --git a/src/llvm-project/clang/test/CodeGenCXX/vtable-key-function.cpp b/src/llvm-project/clang/test/CodeGenCXX/vtable-key-function.cpp
new file mode 100644
index 0000000..bf2e679
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/vtable-key-function.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+// PR5697
+namespace PR5697 {
+struct A {
+ virtual void f() { }
+ A();
+ A(int);
+};
+
+// A does not have a key function, so the first constructor we emit should
+// cause the vtable to be defined (without assertions.)
+// CHECK: @_ZTVN6PR56971AE = linkonce_odr unnamed_addr constant
+A::A() { }
+A::A(int) { }
+}
+
+// Make sure that we don't assert when building the vtable for a class
+// template specialization or explicit instantiation with a key
+// function.
+template<typename T>
+struct Base {
+ virtual ~Base();
+};
+
+template<typename T>
+struct Derived : public Base<T> { };
+
+template<>
+struct Derived<char> : public Base<char> {
+ virtual void anchor();
+};
+
+void Derived<char>::anchor() { }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/vtable-layout-abi-examples.cpp b/src/llvm-project/clang/test/CodeGenCXX/vtable-layout-abi-examples.cpp
new file mode 100644
index 0000000..b8ac6f5
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/vtable-layout-abi-examples.cpp
@@ -0,0 +1,322 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm-only -fdump-vtable-layouts > %t 2>/dev/null
+// RUN: FileCheck --check-prefix=CHECK-1 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-2 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-3 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-4 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-5 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-6 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-7 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-8 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-9 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-10 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-11 %s < %t
+
+/// Examples from the Itanium C++ ABI specification.
+/// http://www.codesourcery.com/public/cxx-abi/
+
+namespace Test1 {
+
+// This is from http://www.codesourcery.com/public/cxx-abi/cxx-vtable-ex.html
+
+// CHECK-1: Vtable for 'Test1::A' (5 entries).
+// CHECK-1-NEXT: 0 | offset_to_top (0)
+// CHECK-1-NEXT: 1 | Test1::A RTTI
+// CHECK-1-NEXT: -- (Test1::A, 0) vtable address --
+// CHECK-1-NEXT: 2 | void Test1::A::f()
+// CHECK-1-NEXT: 3 | void Test1::A::g()
+// CHECK-1-NEXT: 4 | void Test1::A::h()
+struct A {
+ virtual void f ();
+ virtual void g ();
+ virtual void h ();
+ int ia;
+};
+void A::f() {}
+
+// CHECK-2: Vtable for 'Test1::B' (13 entries).
+// CHECK-2-NEXT: 0 | vbase_offset (16)
+// CHECK-2-NEXT: 1 | offset_to_top (0)
+// CHECK-2-NEXT: 2 | Test1::B RTTI
+// CHECK-2-NEXT: -- (Test1::B, 0) vtable address --
+// CHECK-2-NEXT: 3 | void Test1::B::f()
+// CHECK-2-NEXT: 4 | void Test1::B::h()
+// CHECK-2-NEXT: 5 | vcall_offset (-16)
+// CHECK-2-NEXT: 6 | vcall_offset (0)
+// CHECK-2-NEXT: 7 | vcall_offset (-16)
+// CHECK-2-NEXT: 8 | offset_to_top (-16)
+// CHECK-2-NEXT: 9 | Test1::B RTTI
+// CHECK-2-NEXT: -- (Test1::A, 16) vtable address --
+// CHECK-2-NEXT: 10 | void Test1::B::f()
+// CHECK-2-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]
+// CHECK-2-NEXT: 11 | void Test1::A::g()
+// CHECK-2-NEXT: 12 | void Test1::B::h()
+// CHECK-2-NEXT: [this adjustment: 0 non-virtual, -40 vcall offset offset]
+struct B: public virtual A {
+ void f ();
+ void h ();
+ int ib;
+};
+void B::f() {}
+
+// CHECK-3: Vtable for 'Test1::C' (13 entries).
+// CHECK-3-NEXT: 0 | vbase_offset (16)
+// CHECK-3-NEXT: 1 | offset_to_top (0)
+// CHECK-3-NEXT: 2 | Test1::C RTTI
+// CHECK-3-NEXT: -- (Test1::C, 0) vtable address --
+// CHECK-3-NEXT: 3 | void Test1::C::g()
+// CHECK-3-NEXT: 4 | void Test1::C::h()
+// CHECK-3-NEXT: 5 | vcall_offset (-16)
+// CHECK-3-NEXT: 6 | vcall_offset (-16)
+// CHECK-3-NEXT: 7 | vcall_offset (0)
+// CHECK-3-NEXT: 8 | offset_to_top (-16)
+// CHECK-3-NEXT: 9 | Test1::C RTTI
+// CHECK-3-NEXT: -- (Test1::A, 16) vtable address --
+// CHECK-3-NEXT: 10 | void Test1::A::f()
+// CHECK-3-NEXT: 11 | void Test1::C::g()
+// CHECK-3-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset]
+// CHECK-3-NEXT: 12 | void Test1::C::h()
+// CHECK-3-NEXT: [this adjustment: 0 non-virtual, -40 vcall offset offset]
+struct C: public virtual A {
+ void g ();
+ void h ();
+ int ic;
+};
+void C::g() {}
+
+// CHECK-4: Vtable for 'Test1::D' (18 entries).
+// CHECK-4-NEXT: 0 | vbase_offset (32)
+// CHECK-4-NEXT: 1 | offset_to_top (0)
+// CHECK-4-NEXT: 2 | Test1::D RTTI
+// CHECK-4-NEXT: -- (Test1::B, 0) vtable address --
+// CHECK-4-NEXT: -- (Test1::D, 0) vtable address --
+// CHECK-4-NEXT: 3 | void Test1::B::f()
+// CHECK-4-NEXT: 4 | void Test1::D::h()
+// CHECK-4-NEXT: 5 | vbase_offset (16)
+// CHECK-4-NEXT: 6 | offset_to_top (-16)
+// CHECK-4-NEXT: 7 | Test1::D RTTI
+// CHECK-4-NEXT: -- (Test1::C, 16) vtable address --
+// CHECK-4-NEXT: 8 | void Test1::C::g()
+// CHECK-4-NEXT: 9 | void Test1::D::h()
+// CHECK-4-NEXT: [this adjustment: -16 non-virtual]
+// CHECK-4-NEXT: 10 | vcall_offset (-32)
+// CHECK-4-NEXT: 11 | vcall_offset (-16)
+// CHECK-4-NEXT: 12 | vcall_offset (-32)
+// CHECK-4-NEXT: 13 | offset_to_top (-32)
+// CHECK-4-NEXT: 14 | Test1::D RTTI
+// CHECK-4-NEXT: -- (Test1::A, 32) vtable address --
+// CHECK-4-NEXT: 15 | void Test1::B::f()
+// CHECK-4-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]
+// CHECK-4-NEXT: 16 | void Test1::C::g()
+// CHECK-4-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset]
+// CHECK-4-NEXT: 17 | void Test1::D::h()
+// CHECK-4-NEXT: [this adjustment: 0 non-virtual, -40 vcall offset offset]
+struct D: public B, public C {
+ void h ();
+ int id;
+};
+void D::h() { }
+
+struct X {
+ int ix;
+ virtual void x();
+};
+
+// CHECK-5: Vtable for 'Test1::E' (24 entries).
+// CHECK-5-NEXT: 0 | vbase_offset (56)
+// CHECK-5-NEXT: 1 | offset_to_top (0)
+// CHECK-5-NEXT: 2 | Test1::E RTTI
+// CHECK-5-NEXT: -- (Test1::E, 0) vtable address --
+// CHECK-5-NEXT: -- (Test1::X, 0) vtable address --
+// CHECK-5-NEXT: 3 | void Test1::X::x()
+// CHECK-5-NEXT: 4 | void Test1::E::f()
+// CHECK-5-NEXT: 5 | void Test1::E::h()
+// CHECK-5-NEXT: 6 | vbase_offset (40)
+// CHECK-5-NEXT: 7 | offset_to_top (-16)
+// CHECK-5-NEXT: 8 | Test1::E RTTI
+// CHECK-5-NEXT: -- (Test1::B, 16) vtable address --
+// CHECK-5-NEXT: -- (Test1::D, 16) vtable address --
+// CHECK-5-NEXT: 9 | void Test1::E::f()
+// CHECK-5-NEXT: [this adjustment: -16 non-virtual]
+// CHECK-5-NEXT: 10 | void Test1::E::h()
+// CHECK-5-NEXT: [this adjustment: -16 non-virtual]
+// CHECK-5-NEXT: 11 | vbase_offset (24)
+// CHECK-5-NEXT: 12 | offset_to_top (-32)
+// CHECK-5-NEXT: 13 | Test1::E RTTI
+// CHECK-5-NEXT: -- (Test1::C, 32) vtable address --
+// CHECK-5-NEXT: 14 | void Test1::C::g()
+// CHECK-5-NEXT: 15 | void Test1::E::h()
+// CHECK-5-NEXT: [this adjustment: -32 non-virtual]
+// CHECK-5-NEXT: 16 | vcall_offset (-56)
+// CHECK-5-NEXT: 17 | vcall_offset (-24)
+// CHECK-5-NEXT: 18 | vcall_offset (-56)
+// CHECK-5-NEXT: 19 | offset_to_top (-56)
+// CHECK-5-NEXT: 20 | Test1::E RTTI
+// CHECK-5-NEXT: -- (Test1::A, 56) vtable address --
+// CHECK-5-NEXT: 21 | void Test1::E::f()
+// CHECK-5-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]
+// CHECK-5-NEXT: 22 | void Test1::C::g()
+// CHECK-5-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset]
+// CHECK-5-NEXT: 23 | void Test1::E::h()
+// CHECK-5-NEXT: [this adjustment: 0 non-virtual, -40 vcall offset offset]
+struct E : X, D {
+ int ie;
+ void f();
+ void h ();
+};
+void E::f() { }
+
+}
+
+namespace Test2 {
+
+// From http://www.codesourcery.com/public/cxx-abi/abi.html#class-types.
+
+struct A { virtual void f(); };
+struct B : virtual public A { int i; };
+struct C : virtual public A { int j; };
+
+// CHECK-6: Vtable for 'Test2::D' (11 entries).
+// CHECK-6-NEXT: 0 | vbase_offset (0)
+// CHECK-6-NEXT: 1 | vcall_offset (0)
+// CHECK-6-NEXT: 2 | offset_to_top (0)
+// CHECK-6-NEXT: 3 | Test2::D RTTI
+// CHECK-6-NEXT: -- (Test2::A, 0) vtable address --
+// CHECK-6-NEXT: -- (Test2::B, 0) vtable address --
+// CHECK-6-NEXT: -- (Test2::D, 0) vtable address --
+// CHECK-6-NEXT: 4 | void Test2::A::f()
+// CHECK-6-NEXT: 5 | void Test2::D::d()
+// CHECK-6-NEXT: 6 | vbase_offset (-16)
+// CHECK-6-NEXT: 7 | vcall_offset (-16)
+// CHECK-6-NEXT: 8 | offset_to_top (-16)
+// CHECK-6-NEXT: 9 | Test2::D RTTI
+// CHECK-6-NEXT: -- (Test2::C, 16) vtable address --
+// CHECK-6-NEXT: 10 | [unused] void Test2::A::f()
+struct D : public B, public C {
+ virtual void d();
+};
+void D::d() { }
+
+}
+
+namespace Test3 {
+
+// From http://www.codesourcery.com/public/cxx-abi/abi-examples.html#vtable-ctor
+
+struct V1 {
+ int v1;
+ virtual void f();
+};
+
+struct V2 : virtual V1 {
+ int v2;
+ virtual void f();
+};
+
+// CHECK-7: Vtable for 'Test3::C' (14 entries).
+// CHECK-7-NEXT: 0 | vbase_offset (32)
+// CHECK-7-NEXT: 1 | vbase_offset (16)
+// CHECK-7-NEXT: 2 | offset_to_top (0)
+// CHECK-7-NEXT: 3 | Test3::C RTTI
+// CHECK-7-NEXT: -- (Test3::C, 0) vtable address --
+// CHECK-7-NEXT: 4 | void Test3::C::f()
+// CHECK-7-NEXT: 5 | vcall_offset (-16)
+// CHECK-7-NEXT: 6 | offset_to_top (-16)
+// CHECK-7-NEXT: 7 | Test3::C RTTI
+// CHECK-7-NEXT: -- (Test3::V1, 16) vtable address --
+// CHECK-7-NEXT: 8 | void Test3::C::f()
+// CHECK-7-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]
+// CHECK-7-NEXT: 9 | vcall_offset (-32)
+// CHECK-7-NEXT: 10 | vbase_offset (-16)
+// CHECK-7-NEXT: 11 | offset_to_top (-32)
+// CHECK-7-NEXT: 12 | Test3::C RTTI
+// CHECK-7-NEXT: -- (Test3::V2, 32) vtable address --
+// CHECK-7-NEXT: 13 | void Test3::C::f()
+// CHECK-7-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset]
+
+// CHECK-8: Construction vtable for ('Test3::V2', 32) in 'Test3::C' (9 entries).
+// CHECK-8-NEXT: 0 | vcall_offset (0)
+// CHECK-8-NEXT: 1 | vbase_offset (-16)
+// CHECK-8-NEXT: 2 | offset_to_top (0)
+// CHECK-8-NEXT: 3 | Test3::V2 RTTI
+// CHECK-8-NEXT: -- (Test3::V2, 32) vtable address --
+// CHECK-8-NEXT: 4 | void Test3::V2::f()
+// CHECK-8-NEXT: 5 | vcall_offset (16)
+// CHECK-8-NEXT: 6 | offset_to_top (16)
+// CHECK-8-NEXT: 7 | Test3::V2 RTTI
+// CHECK-8-NEXT: -- (Test3::V1, 16) vtable address --
+// CHECK-8-NEXT: 8 | void Test3::V2::f()
+// CHECK-8-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]
+struct C : virtual V1, virtual V2 {
+ int c;
+ virtual void f();
+};
+void C::f() { }
+
+struct B {
+ int b;
+};
+
+// CHECK-9: Vtable for 'Test3::D' (15 entries).
+// CHECK-9-NEXT: 0 | vbase_offset (40)
+// CHECK-9-NEXT: 1 | vbase_offset (24)
+// CHECK-9-NEXT: 2 | offset_to_top (0)
+// CHECK-9-NEXT: 3 | Test3::D RTTI
+// CHECK-9-NEXT: -- (Test3::C, 0) vtable address --
+// CHECK-9-NEXT: -- (Test3::D, 0) vtable address --
+// CHECK-9-NEXT: 4 | void Test3::C::f()
+// CHECK-9-NEXT: 5 | void Test3::D::g()
+// CHECK-9-NEXT: 6 | vcall_offset (-24)
+// CHECK-9-NEXT: 7 | offset_to_top (-24)
+// CHECK-9-NEXT: 8 | Test3::D RTTI
+// CHECK-9-NEXT: -- (Test3::V1, 24) vtable address --
+// CHECK-9-NEXT: 9 | void Test3::C::f()
+// CHECK-9-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]
+// CHECK-9-NEXT: 10 | vcall_offset (-40)
+// CHECK-9-NEXT: 11 | vbase_offset (-16)
+// CHECK-9-NEXT: 12 | offset_to_top (-40)
+// CHECK-9-NEXT: 13 | Test3::D RTTI
+// CHECK-9-NEXT: -- (Test3::V2, 40) vtable address --
+// CHECK-9-NEXT: 14 | void Test3::C::f()
+// CHECK-9-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset]
+
+// CHECK-10: Construction vtable for ('Test3::C', 0) in 'Test3::D' (14 entries).
+// CHECK-10-NEXT: 0 | vbase_offset (40)
+// CHECK-10-NEXT: 1 | vbase_offset (24)
+// CHECK-10-NEXT: 2 | offset_to_top (0)
+// CHECK-10-NEXT: 3 | Test3::C RTTI
+// CHECK-10-NEXT: -- (Test3::C, 0) vtable address --
+// CHECK-10-NEXT: 4 | void Test3::C::f()
+// CHECK-10-NEXT: 5 | vcall_offset (-24)
+// CHECK-10-NEXT: 6 | offset_to_top (-24)
+// CHECK-10-NEXT: 7 | Test3::C RTTI
+// CHECK-10-NEXT: -- (Test3::V1, 24) vtable address --
+// CHECK-10-NEXT: 8 | void Test3::C::f()
+// CHECK-10-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]
+// CHECK-10-NEXT: 9 | vcall_offset (-40)
+// CHECK-10-NEXT: 10 | vbase_offset (-16)
+// CHECK-10-NEXT: 11 | offset_to_top (-40)
+// CHECK-10-NEXT: 12 | Test3::C RTTI
+// CHECK-10-NEXT: -- (Test3::V2, 40) vtable address --
+// CHECK-10-NEXT: 13 | void Test3::C::f()
+// CHECK-10-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset]
+
+// CHECK-11: Construction vtable for ('Test3::V2', 40) in 'Test3::D' (9 entries).
+// CHECK-11-NEXT: 0 | vcall_offset (0)
+// CHECK-11-NEXT: 1 | vbase_offset (-16)
+// CHECK-11-NEXT: 2 | offset_to_top (0)
+// CHECK-11-NEXT: 3 | Test3::V2 RTTI
+// CHECK-11-NEXT: -- (Test3::V2, 40) vtable address --
+// CHECK-11-NEXT: 4 | void Test3::V2::f()
+// CHECK-11-NEXT: 5 | vcall_offset (16)
+// CHECK-11-NEXT: 6 | offset_to_top (16)
+// CHECK-11-NEXT: 7 | Test3::V2 RTTI
+// CHECK-11-NEXT: -- (Test3::V1, 24) vtable address --
+// CHECK-11-NEXT: 8 | void Test3::V2::f()
+// CHECK-11-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]
+struct D : B, C {
+ int d;
+ virtual void g();
+};
+void D::g() { }
+
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/vtable-layout-extreme.cpp b/src/llvm-project/clang/test/CodeGenCXX/vtable-layout-extreme.cpp
new file mode 100644
index 0000000..14e7879
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/vtable-layout-extreme.cpp
@@ -0,0 +1,210 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm-only -fdump-vtable-layouts 2>&1 | FileCheck %s
+
+// A collection of big class hierarchies and their vtables.
+
+namespace Test1 {
+
+class C0
+{
+};
+class C1
+ : virtual public C0
+{
+ int k0;
+};
+class C2
+ : public C0
+ , virtual public C1
+{
+ int k0;
+};
+class C3
+ : virtual public C0
+ , virtual public C1
+ , public C2
+{
+ int k0;
+ int k1;
+ int k2;
+ int k3;
+};
+class C4
+ : public C2
+ , virtual public C3
+ , public C0
+{
+ int k0;
+};
+class C5
+ : public C0
+ , virtual public C4
+ , public C2
+ , public C1
+ , virtual public C3
+{
+ int k0;
+};
+class C6
+ : virtual public C3
+ , public C0
+ , public C5
+ , public C4
+ , public C1
+{
+ int k0;
+};
+class C7
+ : virtual public C5
+ , virtual public C6
+ , virtual public C3
+ , public C4
+ , virtual public C2
+{
+ int k0;
+ int k1;
+};
+class C8
+ : public C7
+ , public C5
+ , public C3
+ , virtual public C4
+ , public C1
+ , public C2
+{
+ int k0;
+ int k1;
+};
+
+// CHECK: Vtable for 'Test1::C9' (87 entries).
+// CHECK-NEXT: 0 | vbase_offset (344)
+// CHECK-NEXT: 1 | vbase_offset (312)
+// CHECK-NEXT: 2 | vbase_offset (184)
+// CHECK-NEXT: 3 | vbase_offset (168)
+// CHECK-NEXT: 4 | vbase_offset (120)
+// CHECK-NEXT: 5 | vbase_offset (48)
+// CHECK-NEXT: 6 | vbase_offset (148)
+// CHECK-NEXT: 7 | vbase_offset (152)
+// CHECK-NEXT: 8 | offset_to_top (0)
+// CHECK-NEXT: 9 | Test1::C9 RTTI
+// CHECK-NEXT: -- (Test1::C2, 0) vtable address --
+// CHECK-NEXT: -- (Test1::C9, 0) vtable address --
+// CHECK-NEXT: 10 | void Test1::C9::f()
+// CHECK-NEXT: 11 | vbase_offset (104)
+// CHECK-NEXT: 12 | vbase_offset (132)
+// CHECK-NEXT: 13 | vbase_offset (136)
+// CHECK-NEXT: 14 | offset_to_top (-16)
+// CHECK-NEXT: 15 | Test1::C9 RTTI
+// CHECK-NEXT: -- (Test1::C2, 16) vtable address --
+// CHECK-NEXT: -- (Test1::C4, 16) vtable address --
+// CHECK-NEXT: 16 | vbase_offset (72)
+// CHECK-NEXT: 17 | vbase_offset (120)
+// CHECK-NEXT: 18 | vbase_offset (100)
+// CHECK-NEXT: 19 | vbase_offset (104)
+// CHECK-NEXT: 20 | offset_to_top (-48)
+// CHECK-NEXT: 21 | Test1::C9 RTTI
+// CHECK-NEXT: -- (Test1::C2, 48) vtable address --
+// CHECK-NEXT: -- (Test1::C5, 48) vtable address --
+// CHECK-NEXT: -- (Test1::C6, 48) vtable address --
+// CHECK-NEXT: 22 | vbase_offset (84)
+// CHECK-NEXT: 23 | offset_to_top (-64)
+// CHECK-NEXT: 24 | Test1::C9 RTTI
+// CHECK-NEXT: -- (Test1::C1, 64) vtable address --
+// CHECK-NEXT: 25 | vbase_offset (32)
+// CHECK-NEXT: 26 | vbase_offset (60)
+// CHECK-NEXT: 27 | vbase_offset (64)
+// CHECK-NEXT: 28 | offset_to_top (-88)
+// CHECK-NEXT: 29 | Test1::C9 RTTI
+// CHECK-NEXT: -- (Test1::C2, 88) vtable address --
+// CHECK-NEXT: -- (Test1::C4, 88) vtable address --
+// CHECK-NEXT: 30 | vbase_offset (44)
+// CHECK-NEXT: 31 | offset_to_top (-104)
+// CHECK-NEXT: 32 | Test1::C9 RTTI
+// CHECK-NEXT: -- (Test1::C1, 104) vtable address --
+// CHECK-NEXT: 33 | vbase_offset (28)
+// CHECK-NEXT: 34 | vbase_offset (32)
+// CHECK-NEXT: 35 | offset_to_top (-120)
+// CHECK-NEXT: 36 | Test1::C9 RTTI
+// CHECK-NEXT: -- (Test1::C2, 120) vtable address --
+// CHECK-NEXT: -- (Test1::C3, 120) vtable address --
+// CHECK-NEXT: 37 | vbase_offset (-4)
+// CHECK-NEXT: 38 | offset_to_top (-152)
+// CHECK-NEXT: 39 | Test1::C9 RTTI
+// CHECK-NEXT: -- (Test1::C1, 152) vtable address --
+// CHECK-NEXT: 40 | vbase_offset (-48)
+// CHECK-NEXT: 41 | vbase_offset (-20)
+// CHECK-NEXT: 42 | vbase_offset (-16)
+// CHECK-NEXT: 43 | offset_to_top (-168)
+// CHECK-NEXT: 44 | Test1::C9 RTTI
+// CHECK-NEXT: -- (Test1::C2, 168) vtable address --
+// CHECK-NEXT: -- (Test1::C4, 168) vtable address --
+// CHECK-NEXT: 45 | vbase_offset (160)
+// CHECK-NEXT: 46 | vbase_offset (-136)
+// CHECK-NEXT: 47 | vbase_offset (-16)
+// CHECK-NEXT: 48 | vbase_offset (128)
+// CHECK-NEXT: 49 | vbase_offset (-64)
+// CHECK-NEXT: 50 | vbase_offset (-36)
+// CHECK-NEXT: 51 | vbase_offset (-32)
+// CHECK-NEXT: 52 | offset_to_top (-184)
+// CHECK-NEXT: 53 | Test1::C9 RTTI
+// CHECK-NEXT: -- (Test1::C2, 184) vtable address --
+// CHECK-NEXT: -- (Test1::C4, 184) vtable address --
+// CHECK-NEXT: -- (Test1::C7, 184) vtable address --
+// CHECK-NEXT: -- (Test1::C8, 184) vtable address --
+// CHECK-NEXT: 54 | vbase_offset (-88)
+// CHECK-NEXT: 55 | vbase_offset (-40)
+// CHECK-NEXT: 56 | vbase_offset (-60)
+// CHECK-NEXT: 57 | vbase_offset (-56)
+// CHECK-NEXT: 58 | offset_to_top (-208)
+// CHECK-NEXT: 59 | Test1::C9 RTTI
+// CHECK-NEXT: -- (Test1::C2, 208) vtable address --
+// CHECK-NEXT: -- (Test1::C5, 208) vtable address --
+// CHECK-NEXT: 60 | vbase_offset (-76)
+// CHECK-NEXT: 61 | offset_to_top (-224)
+// CHECK-NEXT: 62 | Test1::C9 RTTI
+// CHECK-NEXT: -- (Test1::C1, 224) vtable address --
+// CHECK-NEXT: 63 | vbase_offset (-92)
+// CHECK-NEXT: 64 | vbase_offset (-88)
+// CHECK-NEXT: 65 | offset_to_top (-240)
+// CHECK-NEXT: 66 | Test1::C9 RTTI
+// CHECK-NEXT: -- (Test1::C2, 240) vtable address --
+// CHECK-NEXT: -- (Test1::C3, 240) vtable address --
+// CHECK-NEXT: 67 | vbase_offset (-124)
+// CHECK-NEXT: 68 | offset_to_top (-272)
+// CHECK-NEXT: 69 | Test1::C9 RTTI
+// CHECK-NEXT: -- (Test1::C1, 272) vtable address --
+// CHECK-NEXT: 70 | vbase_offset (-140)
+// CHECK-NEXT: 71 | vbase_offset (-136)
+// CHECK-NEXT: 72 | offset_to_top (-288)
+// CHECK-NEXT: 73 | Test1::C9 RTTI
+// CHECK-NEXT: -- (Test1::C2, 288) vtable address --
+// CHECK-NEXT: 74 | vbase_offset (-192)
+// CHECK-NEXT: 75 | vbase_offset (-144)
+// CHECK-NEXT: 76 | vbase_offset (-164)
+// CHECK-NEXT: 77 | vbase_offset (-160)
+// CHECK-NEXT: 78 | offset_to_top (-312)
+// CHECK-NEXT: 79 | Test1::C9 RTTI
+// CHECK-NEXT: -- (Test1::C2, 312) vtable address --
+// CHECK-NEXT: -- (Test1::C5, 312) vtable address --
+// CHECK-NEXT: 80 | vbase_offset (-180)
+// CHECK-NEXT: 81 | offset_to_top (-328)
+// CHECK-NEXT: 82 | Test1::C9 RTTI
+// CHECK-NEXT: -- (Test1::C1, 328) vtable address --
+// CHECK-NEXT: 83 | vbase_offset (-196)
+// CHECK-NEXT: 84 | vbase_offset (-192)
+// CHECK-NEXT: 85 | offset_to_top (-344)
+// CHECK-NEXT: 86 | Test1::C9 RTTI
+class C9
+ : virtual public C6
+ , public C2
+ , public C4
+ , virtual public C8
+{
+ int k0;
+ int k1;
+ int k2;
+ int k3;
+ virtual void f();
+};
+void C9::f() { }
+
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/vtable-layout.cpp b/src/llvm-project/clang/test/CodeGenCXX/vtable-layout.cpp
new file mode 100644
index 0000000..4a47e3c
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/vtable-layout.cpp
@@ -0,0 +1,1928 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm-only -fdump-vtable-layouts > %t
+// RUN: FileCheck --check-prefix=CHECK-1 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-2 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-3 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-4 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-5 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-6 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-7 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-8 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-9 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-10 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-11 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-12 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-13 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-14 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-15 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-16 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-17 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-18 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-19 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-20 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-21 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-22 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-23 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-24 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-25 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-26 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-27 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-28 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-29 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-30 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-31 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-32 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-33 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-34 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-35 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-36 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-37 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-38 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-39 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-40 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-41 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-42 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-43 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-44 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-45 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-46 %s < %t
+
+// For now, just verify this doesn't crash.
+namespace test0 {
+ struct Obj {};
+
+ struct Base { virtual const Obj *foo() = 0; };
+ struct Derived : Base { virtual Obj *foo() { return new Obj(); } };
+
+ void test(Derived *D) { D->foo(); }
+}
+
+namespace Test1 {
+// CHECK-1: Vtable for 'Test1::A' (3 entries).
+// CHECK-1-NEXT: 0 | offset_to_top (0)
+// CHECK-1-NEXT: 1 | Test1::A RTTI
+// CHECK-1-NEXT: -- (Test1::A, 0) vtable address --
+// CHECK-1-NEXT: 2 | void Test1::A::f()
+//
+// CHECK-1: VTable indices for 'Test1::A' (1 entries).
+// CHECK-1-NEXT: 0 | void Test1::A::f()
+struct A {
+ virtual void f();
+};
+void A::f() { }
+
+}
+
+namespace Test2 {
+
+// This is a smoke test of the vtable dumper.
+// CHECK-2: Vtable for 'Test2::A' (9 entries).
+// CHECK-2-NEXT: 0 | offset_to_top (0)
+// CHECK-2-NEXT: 1 | Test2::A RTTI
+// CHECK-2-NEXT: -- (Test2::A, 0) vtable address --
+// CHECK-2-NEXT: 2 | void Test2::A::f()
+// CHECK-2-NEXT: 3 | void Test2::A::f() const
+// CHECK-2-NEXT: 4 | Test2::A *Test2::A::g(int)
+// 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=(const Test2::A &)
+//
+// CHECK-2: VTable indices for 'Test2::A' (7 entries).
+// CHECK-2-NEXT: 0 | void Test2::A::f()
+// CHECK-2-NEXT: 1 | void Test2::A::f() const
+// CHECK-2-NEXT: 2 | Test2::A *Test2::A::g(int)
+// CHECK-2-NEXT: 3 | Test2::A::~A() [complete]
+// CHECK-2-NEXT: 4 | Test2::A::~A() [deleting]
+// CHECK-2-NEXT: 5 | void Test2::A::h()
+// CHECK-2-NEXT: 6 | Test2::A &Test2::A::operator=(const Test2::A &)
+struct A {
+ virtual void f();
+ virtual void f() const;
+
+ virtual A* g(int a);
+ virtual ~A();
+ virtual void h();
+ virtual A& operator=(const A&);
+};
+void A::f() { }
+
+// Another simple vtable dumper test.
+
+// CHECK-3: Vtable for 'Test2::B' (6 entries).
+// CHECK-3-NEXT: 0 | offset_to_top (0)
+// CHECK-3-NEXT: 1 | Test2::B RTTI
+// CHECK-3-NEXT: -- (Test2::B, 0) vtable address --
+// CHECK-3-NEXT: 2 | void Test2::B::f()
+// CHECK-3-NEXT: 3 | void Test2::B::g() [pure]
+// CHECK-3-NEXT: 4 | Test2::B::~B() [complete] [pure]
+// CHECK-3-NEXT: 5 | Test2::B::~B() [deleting] [pure]
+//
+// CHECK-3: VTable indices for 'Test2::B' (4 entries).
+// CHECK-3-NEXT: 0 | void Test2::B::f()
+// CHECK-3-NEXT: 1 | void Test2::B::g()
+// CHECK-3-NEXT: 2 | Test2::B::~B() [complete]
+// CHECK-3-NEXT: 3 | Test2::B::~B() [deleting]
+struct B {
+ virtual void f();
+ virtual void g() = 0;
+ virtual ~B() = 0;
+};
+void B::f() { }
+
+}
+
+namespace Test3 {
+
+// If a function in a derived class overrides a function in a primary base,
+// then the function should not have an entry in the derived class (unless the return
+// value requires adjusting).
+
+// CHECK-4: Vtable for 'Test3::A' (3 entries).
+// CHECK-4-NEXT: 0 | offset_to_top (0)
+// CHECK-4-NEXT: 1 | Test3::A RTTI
+// CHECK-4-NEXT: -- (Test3::A, 0) vtable address --
+// CHECK-4-NEXT: 2 | void Test3::A::f()
+//
+// CHECK-4: VTable indices for 'Test3::A' (1 entries).
+// CHECK-4-NEXT: 0 | void Test3::A::f()
+struct A {
+ virtual void f();
+};
+void A::f() { }
+
+// CHECK-5: Vtable for 'Test3::B' (4 entries).
+// CHECK-5-NEXT: 0 | offset_to_top (0)
+// CHECK-5-NEXT: 1 | Test3::B RTTI
+// CHECK-5-NEXT: -- (Test3::A, 0) vtable address --
+// CHECK-5-NEXT: -- (Test3::B, 0) vtable address --
+// CHECK-5-NEXT: 2 | void Test3::B::f()
+// CHECK-5-NEXT: 3 | void Test3::B::g()
+//
+// CHECK-5: VTable indices for 'Test3::B' (2 entries).
+// CHECK-5-NEXT: 0 | void Test3::B::f()
+// CHECK-5-NEXT: 1 | void Test3::B::g()
+struct B : A {
+ virtual void f();
+ virtual void g();
+};
+void B::f() { }
+
+// CHECK-6: Vtable for 'Test3::C' (5 entries).
+// CHECK-6-NEXT: 0 | offset_to_top (0)
+// CHECK-6-NEXT: 1 | Test3::C RTTI
+// CHECK-6-NEXT: -- (Test3::A, 0) vtable address --
+// CHECK-6-NEXT: -- (Test3::C, 0) vtable address --
+// CHECK-6-NEXT: 2 | void Test3::A::f()
+// CHECK-6-NEXT: 3 | void Test3::C::g()
+// CHECK-6-NEXT: 4 | void Test3::C::h()
+//
+// CHECK-6: VTable indices for 'Test3::C' (2 entries).
+// CHECK-6-NEXT: 1 | void Test3::C::g()
+// CHECK-6-NEXT: 2 | void Test3::C::h()
+struct C : A {
+ virtual void g();
+ virtual void h();
+};
+void C::g() { }
+
+// CHECK-7: Vtable for 'Test3::D' (5 entries).
+// CHECK-7-NEXT: 0 | offset_to_top (0)
+// CHECK-7-NEXT: 1 | Test3::D RTTI
+// CHECK-7-NEXT: -- (Test3::A, 0) vtable address --
+// CHECK-7-NEXT: -- (Test3::B, 0) vtable address --
+// CHECK-7-NEXT: -- (Test3::D, 0) vtable address --
+// CHECK-7-NEXT: 2 | void Test3::D::f()
+// CHECK-7-NEXT: 3 | void Test3::D::g()
+// CHECK-7-NEXT: 4 | void Test3::D::h()
+//
+// CHECK-7: VTable indices for 'Test3::D' (3 entries).
+// CHECK-7-NEXT: 0 | void Test3::D::f()
+// CHECK-7-NEXT: 1 | void Test3::D::g()
+// CHECK-7-NEXT: 2 | void Test3::D::h()
+struct D : B {
+ virtual void f();
+ virtual void g();
+ virtual void h();
+};
+
+void D::f() { }
+}
+
+namespace Test4 {
+
+// Test non-virtual result adjustments.
+
+struct R1 { int r1; };
+struct R2 { int r2; };
+struct R3 : R1, R2 { int r3; };
+
+struct A {
+ virtual R2 *f();
+};
+
+// CHECK-8: Vtable for 'Test4::B' (4 entries).
+// CHECK-8-NEXT: 0 | offset_to_top (0)
+// CHECK-8-NEXT: 1 | Test4::B RTTI
+// CHECK-8-NEXT: -- (Test4::A, 0) vtable address --
+// CHECK-8-NEXT: -- (Test4::B, 0) vtable address --
+// CHECK-8-NEXT: 2 | Test4::R3 *Test4::B::f()
+// CHECK-8-NEXT: [return adjustment: 4 non-virtual]
+// CHECK-8-NEXT: 3 | Test4::R3 *Test4::B::f()
+//
+// CHECK-8: VTable indices for 'Test4::B' (1 entries).
+// CHECK-8-NEXT: 1 | Test4::R3 *Test4::B::f()
+struct B : A {
+ virtual R3 *f();
+};
+R3 *B::f() { return 0; }
+
+// Test virtual result adjustments.
+struct V1 { int v1; };
+struct V2 : virtual V1 { int v1; };
+
+struct C {
+ virtual V1 *f();
+};
+
+// CHECK-9: Vtable for 'Test4::D' (4 entries).
+// CHECK-9-NEXT: 0 | offset_to_top (0)
+// CHECK-9-NEXT: 1 | Test4::D RTTI
+// CHECK-9-NEXT: -- (Test4::C, 0) vtable address --
+// CHECK-9-NEXT: -- (Test4::D, 0) vtable address --
+// CHECK-9-NEXT: 2 | Test4::V2 *Test4::D::f()
+// CHECK-9-NEXT: [return adjustment: 0 non-virtual, -24 vbase offset offset]
+// CHECK-9-NEXT: 3 | Test4::V2 *Test4::D::f()
+//
+// CHECK-9: VTable indices for 'Test4::D' (1 entries).
+// CHECK-9-NEXT: 1 | Test4::V2 *Test4::D::f()
+struct D : C {
+ virtual V2 *f();
+};
+V2 *D::f() { return 0; };
+
+// Virtual result adjustments with an additional non-virtual adjustment.
+struct V3 : virtual R3 { int r3; };
+
+// CHECK-10: Vtable for 'Test4::E' (4 entries).
+// CHECK-10-NEXT: 0 | offset_to_top (0)
+// CHECK-10-NEXT: 1 | Test4::E RTTI
+// CHECK-10-NEXT: -- (Test4::A, 0) vtable address --
+// CHECK-10-NEXT: -- (Test4::E, 0) vtable address --
+// CHECK-10-NEXT: 2 | Test4::V3 *Test4::E::f()
+// CHECK-10-NEXT: [return adjustment: 4 non-virtual, -24 vbase offset offset]
+// CHECK-10-NEXT: 3 | Test4::V3 *Test4::E::f()
+//
+// CHECK-10: VTable indices for 'Test4::E' (1 entries).
+// CHECK-10-NEXT: 1 | Test4::V3 *Test4::E::f()
+struct E : A {
+ virtual V3 *f();
+};
+V3 *E::f() { return 0;}
+
+// Test that a pure virtual member doesn't get a thunk.
+
+// CHECK-11: Vtable for 'Test4::F' (5 entries).
+// CHECK-11-NEXT: 0 | offset_to_top (0)
+// CHECK-11-NEXT: 1 | Test4::F RTTI
+// CHECK-11-NEXT: -- (Test4::A, 0) vtable address --
+// CHECK-11-NEXT: -- (Test4::F, 0) vtable address --
+// CHECK-11-NEXT: 2 | Test4::R3 *Test4::F::f() [pure]
+// CHECK-11-NEXT: 3 | void Test4::F::g()
+// CHECK-11-NEXT: 4 | Test4::R3 *Test4::F::f() [pure]
+//
+// CHECK-11: VTable indices for 'Test4::F' (2 entries).
+// CHECK-11-NEXT: 1 | void Test4::F::g()
+// CHECK-11-NEXT: 2 | Test4::R3 *Test4::F::f()
+struct F : A {
+ virtual void g();
+ virtual R3 *f() = 0;
+};
+void F::g() { }
+
+}
+
+namespace Test5 {
+
+// Simple secondary vtables without 'this' pointer adjustments.
+struct A {
+ virtual void f();
+ virtual void g();
+ int a;
+};
+
+struct B1 : A {
+ virtual void f();
+ int b1;
+};
+
+struct B2 : A {
+ virtual void g();
+ int b2;
+};
+
+// CHECK-12: Vtable for 'Test5::C' (9 entries).
+// CHECK-12-NEXT: 0 | offset_to_top (0)
+// CHECK-12-NEXT: 1 | Test5::C RTTI
+// CHECK-12-NEXT: -- (Test5::A, 0) vtable address --
+// CHECK-12-NEXT: -- (Test5::B1, 0) vtable address --
+// CHECK-12-NEXT: -- (Test5::C, 0) vtable address --
+// CHECK-12-NEXT: 2 | void Test5::B1::f()
+// CHECK-12-NEXT: 3 | void Test5::A::g()
+// CHECK-12-NEXT: 4 | void Test5::C::h()
+// CHECK-12-NEXT: 5 | offset_to_top (-16)
+// CHECK-12-NEXT: 6 | Test5::C RTTI
+// CHECK-12-NEXT: -- (Test5::A, 16) vtable address --
+// CHECK-12-NEXT: -- (Test5::B2, 16) vtable address --
+// CHECK-12-NEXT: 7 | void Test5::A::f()
+// CHECK-12-NEXT: 8 | void Test5::B2::g()
+//
+// CHECK-12: VTable indices for 'Test5::C' (1 entries).
+// CHECK-12-NEXT: 2 | void Test5::C::h()
+struct C : B1, B2 {
+ virtual void h();
+};
+void C::h() { }
+}
+
+namespace Test6 {
+
+// Simple non-virtual 'this' pointer adjustments.
+struct A1 {
+ virtual void f();
+ int a;
+};
+
+struct A2 {
+ virtual void f();
+ int a;
+};
+
+// CHECK-13: Vtable for 'Test6::C' (6 entries).
+// CHECK-13-NEXT: 0 | offset_to_top (0)
+// CHECK-13-NEXT: 1 | Test6::C RTTI
+// CHECK-13-NEXT: -- (Test6::A1, 0) vtable address --
+// CHECK-13-NEXT: -- (Test6::C, 0) vtable address --
+// CHECK-13-NEXT: 2 | void Test6::C::f()
+// CHECK-13-NEXT: 3 | offset_to_top (-16)
+// CHECK-13-NEXT: 4 | Test6::C RTTI
+// CHECK-13-NEXT: -- (Test6::A2, 16) vtable address --
+// CHECK-13-NEXT: 5 | void Test6::C::f()
+// CHECK-13-NEXT: [this adjustment: -16 non-virtual]
+//
+// CHECK-13: VTable indices for 'Test6::C' (1 entries).
+// CHECK-13-NEXT: 0 | void Test6::C::f()
+struct C : A1, A2 {
+ virtual void f();
+};
+void C::f() { }
+
+}
+
+namespace Test7 {
+
+// Test that the D::f overrider for A::f have different 'this' pointer
+// adjustments in the two A base subobjects.
+
+struct A {
+ virtual void f();
+ int a;
+};
+
+struct B1 : A { };
+struct B2 : A { };
+
+struct C { virtual void c(); };
+
+// CHECK-14: Vtable for 'Test7::D' (10 entries).
+// CHECK-14-NEXT: 0 | offset_to_top (0)
+// CHECK-14-NEXT: 1 | Test7::D RTTI
+// CHECK-14-NEXT: -- (Test7::C, 0) vtable address --
+// CHECK-14-NEXT: -- (Test7::D, 0) vtable address --
+// CHECK-14-NEXT: 2 | void Test7::C::c()
+// CHECK-14-NEXT: 3 | void Test7::D::f()
+// CHECK-14-NEXT: 4 | offset_to_top (-8)
+// CHECK-14-NEXT: 5 | Test7::D RTTI
+// CHECK-14-NEXT: -- (Test7::A, 8) vtable address --
+// CHECK-14-NEXT: -- (Test7::B1, 8) vtable address --
+// CHECK-14-NEXT: 6 | void Test7::D::f()
+// CHECK-14-NEXT: [this adjustment: -8 non-virtual]
+// CHECK-14-NEXT: 7 | offset_to_top (-24)
+// CHECK-14-NEXT: 8 | Test7::D RTTI
+// CHECK-14-NEXT: -- (Test7::A, 24) vtable address --
+// CHECK-14-NEXT: -- (Test7::B2, 24) vtable address --
+// CHECK-14-NEXT: 9 | void Test7::D::f()
+// CHECK-14-NEXT: [this adjustment: -24 non-virtual]
+//
+// CHECK-14: VTable indices for 'Test7::D' (1 entries).
+// CHECK-14-NEXT: 1 | void Test7::D::f()
+struct D : C, B1, B2 {
+ virtual void f();
+};
+void D::f() { }
+
+}
+
+namespace Test8 {
+
+// Test that we don't try to layout vtables for classes that don't have
+// virtual bases or virtual member functions.
+
+struct A { };
+
+// CHECK-15: Vtable for 'Test8::B' (3 entries).
+// CHECK-15-NEXT: 0 | offset_to_top (0)
+// CHECK-15-NEXT: 1 | Test8::B RTTI
+// CHECK-15-NEXT: -- (Test8::B, 0) vtable address --
+// CHECK-15-NEXT: 2 | void Test8::B::f()
+//
+// CHECK-15: VTable indices for 'Test8::B' (1 entries).
+// CHECK-15-NEXT: 0 | void Test8::B::f()
+struct B : A {
+ virtual void f();
+};
+void B::f() { }
+
+}
+
+namespace Test9 {
+
+// Simple test of vbase offsets.
+
+struct A1 { int a1; };
+struct A2 { int a2; };
+
+// CHECK-16: Vtable for 'Test9::B' (5 entries).
+// CHECK-16-NEXT: 0 | vbase_offset (16)
+// CHECK-16-NEXT: 1 | vbase_offset (12)
+// CHECK-16-NEXT: 2 | offset_to_top (0)
+// CHECK-16-NEXT: 3 | Test9::B RTTI
+// CHECK-16-NEXT: -- (Test9::B, 0) vtable address --
+// CHECK-16-NEXT: 4 | void Test9::B::f()
+//
+// CHECK-16: VTable indices for 'Test9::B' (1 entries).
+// CHECK-16-NEXT: 0 | void Test9::B::f()
+struct B : virtual A1, virtual A2 {
+ int b;
+
+ virtual void f();
+};
+
+
+void B::f() { }
+
+}
+
+namespace Test10 {
+
+// Test for a bug where we would not emit secondary vtables for bases
+// of a primary base.
+struct A1 { virtual void a1(); };
+struct A2 { virtual void a2(); };
+
+// CHECK-17: Vtable for 'Test10::C' (7 entries).
+// CHECK-17-NEXT: 0 | offset_to_top (0)
+// CHECK-17-NEXT: 1 | Test10::C RTTI
+// CHECK-17-NEXT: -- (Test10::A1, 0) vtable address --
+// CHECK-17-NEXT: -- (Test10::B, 0) vtable address --
+// CHECK-17-NEXT: -- (Test10::C, 0) vtable address --
+// CHECK-17-NEXT: 2 | void Test10::A1::a1()
+// CHECK-17-NEXT: 3 | void Test10::C::f()
+// CHECK-17-NEXT: 4 | offset_to_top (-8)
+// CHECK-17-NEXT: 5 | Test10::C RTTI
+// CHECK-17-NEXT: -- (Test10::A2, 8) vtable address --
+// CHECK-17-NEXT: 6 | void Test10::A2::a2()
+//
+// CHECK-17: VTable indices for 'Test10::C' (1 entries).
+// CHECK-17-NEXT: 1 | void Test10::C::f()
+struct B : A1, A2 {
+ int b;
+};
+
+struct C : B {
+ virtual void f();
+};
+void C::f() { }
+
+}
+
+namespace Test11 {
+
+// Very simple test of vtables for virtual bases.
+struct A1 { int a; };
+struct A2 { int b; };
+
+struct B : A1, virtual A2 {
+ int b;
+};
+
+// CHECK-18: Vtable for 'Test11::C' (8 entries).
+// CHECK-18-NEXT: 0 | vbase_offset (24)
+// CHECK-18-NEXT: 1 | vbase_offset (8)
+// CHECK-18-NEXT: 2 | offset_to_top (0)
+// CHECK-18-NEXT: 3 | Test11::C RTTI
+// CHECK-18-NEXT: -- (Test11::C, 0) vtable address --
+// CHECK-18-NEXT: 4 | void Test11::C::f()
+// CHECK-18-NEXT: 5 | vbase_offset (16)
+// CHECK-18-NEXT: 6 | offset_to_top (-8)
+// CHECK-18-NEXT: 7 | Test11::C RTTI
+//
+// CHECK-18: VTable indices for 'Test11::C' (1 entries).
+// CHECK-18-NEXT: 0 | void Test11::C::f()
+struct C : virtual B {
+ virtual void f();
+};
+void C::f() { }
+
+}
+
+namespace Test12 {
+
+// Test that the right vcall offsets are generated in the right order.
+
+// CHECK-19: Vtable for 'Test12::B' (19 entries).
+// CHECK-19-NEXT: 0 | vbase_offset (8)
+// CHECK-19-NEXT: 1 | offset_to_top (0)
+// CHECK-19-NEXT: 2 | Test12::B RTTI
+// CHECK-19-NEXT: -- (Test12::B, 0) vtable address --
+// CHECK-19-NEXT: 3 | void Test12::B::f()
+// CHECK-19-NEXT: 4 | void Test12::B::a()
+// CHECK-19-NEXT: 5 | vcall_offset (32)
+// CHECK-19-NEXT: 6 | vcall_offset (16)
+// CHECK-19-NEXT: 7 | vcall_offset (-8)
+// CHECK-19-NEXT: 8 | vcall_offset (0)
+// CHECK-19-NEXT: 9 | offset_to_top (-8)
+// CHECK-19-NEXT: 10 | Test12::B RTTI
+// CHECK-19-NEXT: -- (Test12::A, 8) vtable address --
+// CHECK-19-NEXT: -- (Test12::A1, 8) vtable address --
+// CHECK-19-NEXT: 11 | void Test12::A1::a1()
+// CHECK-19-NEXT: 12 | void Test12::B::a()
+// CHECK-19-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset]
+// CHECK-19-NEXT: 13 | offset_to_top (-24)
+// CHECK-19-NEXT: 14 | Test12::B RTTI
+// CHECK-19-NEXT: -- (Test12::A2, 24) vtable address --
+// CHECK-19-NEXT: 15 | void Test12::A2::a2()
+// CHECK-19-NEXT: 16 | offset_to_top (-40)
+// CHECK-19-NEXT: 17 | Test12::B RTTI
+// CHECK-19-NEXT: -- (Test12::A3, 40) vtable address --
+// CHECK-19-NEXT: 18 | void Test12::A3::a3()
+//
+// CHECK-19: VTable indices for 'Test12::B' (2 entries).
+// CHECK-19-NEXT: 0 | void Test12::B::f()
+// CHECK-19-NEXT: 1 | void Test12::B::a()
+struct A1 {
+ virtual void a1();
+ int a;
+};
+
+struct A2 {
+ virtual void a2();
+ int a;
+};
+
+struct A3 {
+ virtual void a3();
+ int a;
+};
+
+struct A : A1, A2, A3 {
+ virtual void a();
+ int i;
+};
+
+struct B : virtual A {
+ virtual void f();
+
+ virtual void a();
+};
+void B::f() { }
+
+}
+
+namespace Test13 {
+
+// Test that we don't try to emit a vtable for 'A' twice.
+struct A {
+ virtual void f();
+};
+
+struct B : virtual A {
+ virtual void f();
+};
+
+// CHECK-20: Vtable for 'Test13::C' (6 entries).
+// CHECK-20-NEXT: 0 | vbase_offset (0)
+// CHECK-20-NEXT: 1 | vbase_offset (0)
+// CHECK-20-NEXT: 2 | vcall_offset (0)
+// CHECK-20-NEXT: 3 | offset_to_top (0)
+// CHECK-20-NEXT: 4 | Test13::C RTTI
+// CHECK-20-NEXT: -- (Test13::A, 0) vtable address --
+// CHECK-20-NEXT: -- (Test13::B, 0) vtable address --
+// CHECK-20-NEXT: -- (Test13::C, 0) vtable address --
+// CHECK-20-NEXT: 5 | void Test13::C::f()
+//
+// CHECK-20: VTable indices for 'Test13::C' (1 entries).
+// CHECK-20-NEXT: 0 | void Test13::C::f()
+struct C : virtual B, virtual A {
+ virtual void f();
+};
+void C::f() { }
+
+}
+
+namespace Test14 {
+
+// Verify that we handle A being a non-virtual base of B, which is a virtual base.
+
+struct A {
+ virtual void f();
+};
+
+struct B : A { };
+
+struct C : virtual B { };
+
+// CHECK-21: Vtable for 'Test14::D' (5 entries).
+// CHECK-21-NEXT: 0 | vbase_offset (0)
+// CHECK-21-NEXT: 1 | vcall_offset (0)
+// CHECK-21-NEXT: 2 | offset_to_top (0)
+// CHECK-21-NEXT: 3 | Test14::D RTTI
+// CHECK-21-NEXT: -- (Test14::A, 0) vtable address --
+// CHECK-21-NEXT: -- (Test14::B, 0) vtable address --
+// CHECK-21-NEXT: -- (Test14::C, 0) vtable address --
+// CHECK-21-NEXT: -- (Test14::D, 0) vtable address --
+// CHECK-21-NEXT: 4 | void Test14::D::f()
+//
+// CHECK-21: VTable indices for 'Test14::D' (1 entries).
+// CHECK-21-NEXT: 0 | void Test14::D::f()
+struct D : C, virtual B {
+ virtual void f();
+};
+void D::f() { }
+
+}
+
+namespace Test15 {
+
+// Test that we don't emit an extra vtable for B since it's a primary base of C.
+struct A { virtual void a(); };
+struct B { virtual void b(); };
+
+struct C : virtual B { };
+
+// CHECK-22: Vtable for 'Test15::D' (11 entries).
+// CHECK-22-NEXT: 0 | vbase_offset (8)
+// CHECK-22-NEXT: 1 | vbase_offset (8)
+// CHECK-22-NEXT: 2 | offset_to_top (0)
+// CHECK-22-NEXT: 3 | Test15::D RTTI
+// CHECK-22-NEXT: -- (Test15::A, 0) vtable address --
+// CHECK-22-NEXT: -- (Test15::D, 0) vtable address --
+// CHECK-22-NEXT: 4 | void Test15::A::a()
+// CHECK-22-NEXT: 5 | void Test15::D::f()
+// CHECK-22-NEXT: 6 | vbase_offset (0)
+// CHECK-22-NEXT: 7 | vcall_offset (0)
+// CHECK-22-NEXT: 8 | offset_to_top (-8)
+// CHECK-22-NEXT: 9 | Test15::D RTTI
+// CHECK-22-NEXT: -- (Test15::B, 8) vtable address --
+// CHECK-22-NEXT: -- (Test15::C, 8) vtable address --
+// CHECK-22-NEXT: 10 | void Test15::B::b()
+//
+// CHECK-22: VTable indices for 'Test15::D' (1 entries).
+// CHECK-22-NEXT: 1 | void Test15::D::f()
+struct D : A, virtual B, virtual C {
+ virtual void f();
+};
+void D::f() { }
+
+}
+
+namespace Test16 {
+
+// Test that destructors share vcall offsets.
+
+struct A { virtual ~A(); };
+struct B { virtual ~B(); };
+
+struct C : A, B { virtual ~C(); };
+
+// CHECK-23: Vtable for 'Test16::D' (15 entries).
+// CHECK-23-NEXT: 0 | vbase_offset (8)
+// CHECK-23-NEXT: 1 | offset_to_top (0)
+// CHECK-23-NEXT: 2 | Test16::D RTTI
+// CHECK-23-NEXT: -- (Test16::D, 0) vtable address --
+// CHECK-23-NEXT: 3 | void Test16::D::f()
+// CHECK-23-NEXT: 4 | Test16::D::~D() [complete]
+// CHECK-23-NEXT: 5 | Test16::D::~D() [deleting]
+// CHECK-23-NEXT: 6 | vcall_offset (-8)
+// CHECK-23-NEXT: 7 | offset_to_top (-8)
+// CHECK-23-NEXT: 8 | Test16::D RTTI
+// CHECK-23-NEXT: -- (Test16::A, 8) vtable address --
+// CHECK-23-NEXT: -- (Test16::C, 8) vtable address --
+// CHECK-23-NEXT: 9 | Test16::D::~D() [complete]
+// CHECK-23-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]
+// CHECK-23-NEXT: 10 | Test16::D::~D() [deleting]
+// CHECK-23-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]
+// CHECK-23-NEXT: 11 | offset_to_top (-16)
+// CHECK-23-NEXT: 12 | Test16::D RTTI
+// CHECK-23-NEXT: -- (Test16::B, 16) vtable address --
+// CHECK-23-NEXT: 13 | Test16::D::~D() [complete]
+// CHECK-23-NEXT: [this adjustment: -8 non-virtual, -24 vcall offset offset]
+// CHECK-23-NEXT: 14 | Test16::D::~D() [deleting]
+// CHECK-23-NEXT: [this adjustment: -8 non-virtual, -24 vcall offset offset]
+//
+// CHECK-23: VTable indices for 'Test16::D' (3 entries).
+// CHECK-23-NEXT: 0 | void Test16::D::f()
+// CHECK-23-NEXT: 1 | Test16::D::~D() [complete]
+// CHECK-23-NEXT: 2 | Test16::D::~D() [deleting]
+struct D : virtual C {
+ virtual void f();
+};
+void D::f() { }
+
+}
+
+namespace Test17 {
+
+// Test that we don't mark E::f in the C-in-E vtable as unused.
+struct A { virtual void f(); };
+struct B : virtual A { virtual void f(); };
+struct C : virtual A { virtual void f(); };
+struct D : virtual B, virtual C { virtual void f(); };
+
+// CHECK-24: Vtable for 'Test17::E' (13 entries).
+// CHECK-24-NEXT: 0 | vbase_offset (0)
+// CHECK-24-NEXT: 1 | vbase_offset (8)
+// CHECK-24-NEXT: 2 | vbase_offset (0)
+// CHECK-24-NEXT: 3 | vbase_offset (0)
+// CHECK-24-NEXT: 4 | vcall_offset (0)
+// CHECK-24-NEXT: 5 | offset_to_top (0)
+// CHECK-24-NEXT: 6 | Test17::E RTTI
+// CHECK-24-NEXT: -- (Test17::A, 0) vtable address --
+// CHECK-24-NEXT: -- (Test17::B, 0) vtable address --
+// CHECK-24-NEXT: -- (Test17::D, 0) vtable address --
+// CHECK-24-NEXT: -- (Test17::E, 0) vtable address --
+// CHECK-24-NEXT: 7 | void Test17::E::f()
+// CHECK-24-NEXT: 8 | vbase_offset (-8)
+// CHECK-24-NEXT: 9 | vcall_offset (-8)
+// CHECK-24-NEXT: 10 | offset_to_top (-8)
+// CHECK-24-NEXT: 11 | Test17::E RTTI
+// CHECK-24-NEXT: -- (Test17::C, 8) vtable address --
+// CHECK-24-NEXT: 12 | void Test17::E::f()
+// CHECK-24-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]
+//
+// CHECK-24: VTable indices for 'Test17::E' (1 entries).
+// CHECK-24-NEXT: 0 | void Test17::E::f()
+class E : virtual D {
+ virtual void f();
+};
+void E::f() {}
+
+}
+
+namespace Test18 {
+
+// Test that we compute the right 'this' adjustment offsets.
+
+struct A {
+ virtual void f();
+ virtual void g();
+};
+
+struct B : virtual A {
+ virtual void f();
+};
+
+struct C : A, B {
+ virtual void g();
+};
+
+// CHECK-25: Vtable for 'Test18::D' (24 entries).
+// CHECK-25-NEXT: 0 | vbase_offset (8)
+// CHECK-25-NEXT: 1 | vbase_offset (0)
+// CHECK-25-NEXT: 2 | vbase_offset (0)
+// CHECK-25-NEXT: 3 | vcall_offset (8)
+// CHECK-25-NEXT: 4 | vcall_offset (0)
+// CHECK-25-NEXT: 5 | offset_to_top (0)
+// CHECK-25-NEXT: 6 | Test18::D RTTI
+// CHECK-25-NEXT: -- (Test18::A, 0) vtable address --
+// CHECK-25-NEXT: -- (Test18::B, 0) vtable address --
+// CHECK-25-NEXT: -- (Test18::D, 0) vtable address --
+// CHECK-25-NEXT: 7 | void Test18::D::f()
+// CHECK-25-NEXT: 8 | void Test18::C::g()
+// CHECK-25-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset]
+// CHECK-25-NEXT: 9 | void Test18::D::h()
+// CHECK-25-NEXT: 10 | vcall_offset (0)
+// CHECK-25-NEXT: 11 | vcall_offset (-8)
+// CHECK-25-NEXT: 12 | vbase_offset (-8)
+// CHECK-25-NEXT: 13 | offset_to_top (-8)
+// CHECK-25-NEXT: 14 | Test18::D RTTI
+// CHECK-25-NEXT: -- (Test18::A, 8) vtable address --
+// CHECK-25-NEXT: -- (Test18::C, 8) vtable address --
+// CHECK-25-NEXT: 15 | void Test18::D::f()
+// CHECK-25-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset]
+// CHECK-25-NEXT: 16 | void Test18::C::g()
+// CHECK-25-NEXT: 17 | vbase_offset (-16)
+// CHECK-25-NEXT: 18 | vcall_offset (-8)
+// CHECK-25-NEXT: 19 | vcall_offset (-16)
+// CHECK-25-NEXT: 20 | offset_to_top (-16)
+// CHECK-25-NEXT: 21 | Test18::D RTTI
+// CHECK-25-NEXT: -- (Test18::B, 16) vtable address --
+// CHECK-25-NEXT: 22 | void Test18::D::f()
+// CHECK-25-NEXT: [this adjustment: -8 non-virtual, -32 vcall offset offset]
+// CHECK-25-NEXT: 23 | [unused] void Test18::C::g()
+//
+// CHECK-25: VTable indices for 'Test18::D' (2 entries).
+// CHECK-25-NEXT: 0 | void Test18::D::f()
+// CHECK-25-NEXT: 2 | void Test18::D::h()
+
+// CHECK-25: Construction vtable for ('Test18::B', 0) in 'Test18::D' (7 entries).
+// CHECK-25-NEXT: 0 | vbase_offset (0)
+// CHECK-25-NEXT: 1 | vcall_offset (0)
+// CHECK-25-NEXT: 2 | vcall_offset (0)
+// CHECK-25-NEXT: 3 | offset_to_top (0)
+// CHECK-25-NEXT: 4 | Test18::B RTTI
+// CHECK-25-NEXT: -- (Test18::A, 0) vtable address --
+// CHECK-25-NEXT: -- (Test18::B, 0) vtable address --
+// CHECK-25-NEXT: 5 | void Test18::B::f()
+// CHECK-25-NEXT: 6 | void Test18::A::g()
+
+// CHECK-25: Construction vtable for ('Test18::C', 8) in 'Test18::D' (20 entries).
+// CHECK-25-NEXT: 0 | vcall_offset (0)
+// CHECK-25-NEXT: 1 | vcall_offset (0)
+// CHECK-25-NEXT: 2 | vbase_offset (-8)
+// CHECK-25-NEXT: 3 | offset_to_top (0)
+// CHECK-25-NEXT: 4 | Test18::C RTTI
+// CHECK-25-NEXT: -- (Test18::A, 8) vtable address --
+// CHECK-25-NEXT: -- (Test18::C, 8) vtable address --
+// CHECK-25-NEXT: 5 | void Test18::A::f()
+// CHECK-25-NEXT: 6 | void Test18::C::g()
+// CHECK-25-NEXT: 7 | vbase_offset (-16)
+// CHECK-25-NEXT: 8 | vcall_offset (-8)
+// CHECK-25-NEXT: 9 | vcall_offset (0)
+// CHECK-25-NEXT: 10 | offset_to_top (-8)
+// CHECK-25-NEXT: 11 | Test18::C RTTI
+// CHECK-25-NEXT: -- (Test18::B, 16) vtable address --
+// CHECK-25-NEXT: 12 | void Test18::B::f()
+// CHECK-25-NEXT: 13 | [unused] void Test18::C::g()
+// CHECK-25-NEXT: 14 | vcall_offset (8)
+// CHECK-25-NEXT: 15 | vcall_offset (16)
+// CHECK-25-NEXT: 16 | offset_to_top (8)
+// CHECK-25-NEXT: 17 | Test18::C RTTI
+// CHECK-25-NEXT: -- (Test18::A, 0) vtable address --
+// CHECK-25-NEXT: 18 | void Test18::B::f()
+// CHECK-25-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]
+// CHECK-25-NEXT: 19 | void Test18::C::g()
+// CHECK-25-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset]
+
+// CHECK-25: Construction vtable for ('Test18::B', 16) in 'Test18::D' (13 entries).
+// CHECK-25-NEXT: 0 | vbase_offset (-16)
+// CHECK-25-NEXT: 1 | vcall_offset (-16)
+// CHECK-25-NEXT: 2 | vcall_offset (0)
+// CHECK-25-NEXT: 3 | offset_to_top (0)
+// CHECK-25-NEXT: 4 | Test18::B RTTI
+// CHECK-25-NEXT: -- (Test18::B, 16) vtable address --
+// CHECK-25-NEXT: 5 | void Test18::B::f()
+// CHECK-25-NEXT: 6 | [unused] void Test18::A::g()
+// CHECK-25-NEXT: 7 | vcall_offset (0)
+// CHECK-25-NEXT: 8 | vcall_offset (16)
+// CHECK-25-NEXT: 9 | offset_to_top (16)
+// CHECK-25-NEXT: 10 | Test18::B RTTI
+// CHECK-25-NEXT: -- (Test18::A, 0) vtable address --
+// CHECK-25-NEXT: 11 | void Test18::B::f()
+// CHECK-25-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]
+// CHECK-25-NEXT: 12 | void Test18::A::g()
+struct D : virtual B, virtual C, virtual A
+{
+ virtual void f();
+ virtual void h();
+};
+void D::f() {}
+
+}
+
+namespace Test19 {
+
+// Another 'this' adjustment test.
+
+struct A {
+ int a;
+
+ virtual void f();
+};
+
+struct B : A {
+ int b;
+
+ virtual void g();
+};
+
+struct C {
+ virtual void c();
+};
+
+// CHECK-26: Vtable for 'Test19::D' (13 entries).
+// CHECK-26-NEXT: 0 | vbase_offset (24)
+// CHECK-26-NEXT: 1 | offset_to_top (0)
+// CHECK-26-NEXT: 2 | Test19::D RTTI
+// CHECK-26-NEXT: -- (Test19::C, 0) vtable address --
+// CHECK-26-NEXT: -- (Test19::D, 0) vtable address --
+// CHECK-26-NEXT: 3 | void Test19::C::c()
+// CHECK-26-NEXT: 4 | void Test19::D::f()
+// CHECK-26-NEXT: 5 | offset_to_top (-8)
+// CHECK-26-NEXT: 6 | Test19::D RTTI
+// CHECK-26-NEXT: -- (Test19::A, 8) vtable address --
+// CHECK-26-NEXT: -- (Test19::B, 8) vtable address --
+// CHECK-26-NEXT: 7 | void Test19::D::f()
+// CHECK-26-NEXT: [this adjustment: -8 non-virtual]
+// CHECK-26-NEXT: 8 | void Test19::B::g()
+// CHECK-26-NEXT: 9 | vcall_offset (-24)
+// CHECK-26-NEXT: 10 | offset_to_top (-24)
+// CHECK-26-NEXT: 11 | Test19::D RTTI
+// CHECK-26-NEXT: -- (Test19::A, 24) vtable address --
+// CHECK-26-NEXT: 12 | void Test19::D::f()
+// CHECK-26-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]
+//
+// CHECK-26: VTable indices for 'Test19::D' (1 entries).
+// CHECK-26-NEXT: 1 | void Test19::D::f()
+struct D : C, B, virtual A {
+ virtual void f();
+};
+void D::f() { }
+
+}
+
+namespace Test20 {
+
+// pure virtual member functions should never have 'this' adjustments.
+
+struct A {
+ virtual void f() = 0;
+ virtual void g();
+};
+
+struct B : A { };
+
+// CHECK-27: Vtable for 'Test20::C' (9 entries).
+// CHECK-27-NEXT: 0 | offset_to_top (0)
+// CHECK-27-NEXT: 1 | Test20::C RTTI
+// CHECK-27-NEXT: -- (Test20::A, 0) vtable address --
+// CHECK-27-NEXT: -- (Test20::C, 0) vtable address --
+// CHECK-27-NEXT: 2 | void Test20::C::f() [pure]
+// CHECK-27-NEXT: 3 | void Test20::A::g()
+// CHECK-27-NEXT: 4 | void Test20::C::h()
+// CHECK-27-NEXT: 5 | offset_to_top (-8)
+// CHECK-27-NEXT: 6 | Test20::C RTTI
+// CHECK-27-NEXT: -- (Test20::A, 8) vtable address --
+// CHECK-27-NEXT: -- (Test20::B, 8) vtable address --
+// CHECK-27-NEXT: 7 | void Test20::C::f() [pure]
+// CHECK-27-NEXT: 8 | void Test20::A::g()
+//
+// CHECK-27: VTable indices for 'Test20::C' (2 entries).
+// CHECK-27-NEXT: 0 | void Test20::C::f()
+// CHECK-27-NEXT: 2 | void Test20::C::h()
+struct C : A, B {
+ virtual void f() = 0;
+ virtual void h();
+};
+void C::h() { }
+
+}
+
+namespace Test21 {
+
+// Test that we get vbase offsets right in secondary vtables.
+struct A {
+ virtual void f();
+};
+
+struct B : virtual A { };
+class C : virtual B { };
+class D : virtual C { };
+
+class E : virtual C { };
+
+// CHECK-28: Vtable for 'Test21::F' (16 entries).
+// CHECK-28-NEXT: 0 | vbase_offset (8)
+// CHECK-28-NEXT: 1 | vbase_offset (0)
+// CHECK-28-NEXT: 2 | vbase_offset (0)
+// CHECK-28-NEXT: 3 | vbase_offset (0)
+// CHECK-28-NEXT: 4 | vbase_offset (0)
+// CHECK-28-NEXT: 5 | vcall_offset (0)
+// CHECK-28-NEXT: 6 | offset_to_top (0)
+// CHECK-28-NEXT: 7 | Test21::F RTTI
+// CHECK-28-NEXT: -- (Test21::A, 0) vtable address --
+// CHECK-28-NEXT: -- (Test21::B, 0) vtable address --
+// CHECK-28-NEXT: -- (Test21::C, 0) vtable address --
+// CHECK-28-NEXT: -- (Test21::D, 0) vtable address --
+// CHECK-28-NEXT: -- (Test21::F, 0) vtable address --
+// CHECK-28-NEXT: 8 | void Test21::F::f()
+// CHECK-28-NEXT: 9 | vbase_offset (-8)
+// CHECK-28-NEXT: 10 | vbase_offset (-8)
+// CHECK-28-NEXT: 11 | vbase_offset (-8)
+// CHECK-28-NEXT: 12 | vcall_offset (-8)
+// CHECK-28-NEXT: 13 | offset_to_top (-8)
+// CHECK-28-NEXT: 14 | Test21::F RTTI
+// CHECK-28-NEXT: -- (Test21::E, 8) vtable address --
+// CHECK-28-NEXT: 15 | [unused] void Test21::F::f()
+//
+// CHECK-28: Virtual base offset offsets for 'Test21::F' (5 entries).
+// CHECK-28-NEXT: Test21::A | -32
+// CHECK-28-NEXT: Test21::B | -40
+// CHECK-28-NEXT: Test21::C | -48
+// CHECK-28-NEXT: Test21::D | -56
+// CHECK-28-NEXT: Test21::E | -64
+//
+// CHECK-28: VTable indices for 'Test21::F' (1 entries).
+// CHECK-28-NEXT: 0 | void Test21::F::f()
+class F : virtual D, virtual E {
+ virtual void f();
+};
+void F::f() { }
+
+}
+
+namespace Test22 {
+
+// Very simple construction vtable test.
+struct V1 {
+ int v1;
+};
+
+struct V2 : virtual V1 {
+ int v2;
+};
+
+// CHECK-29: Vtable for 'Test22::C' (8 entries).
+// CHECK-29-NEXT: 0 | vbase_offset (16)
+// CHECK-29-NEXT: 1 | vbase_offset (12)
+// CHECK-29-NEXT: 2 | offset_to_top (0)
+// CHECK-29-NEXT: 3 | Test22::C RTTI
+// CHECK-29-NEXT: -- (Test22::C, 0) vtable address --
+// CHECK-29-NEXT: 4 | void Test22::C::f()
+// CHECK-29-NEXT: 5 | vbase_offset (-4)
+// CHECK-29-NEXT: 6 | offset_to_top (-16)
+// CHECK-29-NEXT: 7 | Test22::C RTTI
+// CHECK-29-NEXT: -- (Test22::V2, 16) vtable address --
+//
+// CHECK-29: VTable indices for 'Test22::C' (1 entries).
+// CHECK-29-NEXT: 0 | void Test22::C::f()
+
+// CHECK-29: Construction vtable for ('Test22::V2', 16) in 'Test22::C' (3 entries).
+// CHECK-29-NEXT: 0 | vbase_offset (-4)
+// CHECK-29-NEXT: 1 | offset_to_top (0)
+// CHECK-29-NEXT: 2 | Test22::V2 RTTI
+
+struct C : virtual V1, virtual V2 {
+ int c;
+ virtual void f();
+};
+void C::f() { }
+
+}
+
+namespace Test23 {
+
+struct A {
+ int a;
+};
+
+struct B : virtual A {
+ int b;
+};
+
+struct C : A, virtual B {
+ int c;
+};
+
+// CHECK-30: Vtable for 'Test23::D' (7 entries).
+// CHECK-30-NEXT: 0 | vbase_offset (20)
+// CHECK-30-NEXT: 1 | vbase_offset (24)
+// CHECK-30-NEXT: 2 | offset_to_top (0)
+// CHECK-30-NEXT: 3 | Test23::D RTTI
+// CHECK-30-NEXT: -- (Test23::C, 0) vtable address --
+// CHECK-30-NEXT: -- (Test23::D, 0) vtable address --
+// CHECK-30-NEXT: 4 | vbase_offset (-4)
+// CHECK-30-NEXT: 5 | offset_to_top (-24)
+// CHECK-30-NEXT: 6 | Test23::D RTTI
+// CHECK-30-NEXT: -- (Test23::B, 24) vtable address --
+
+// CHECK-30: Construction vtable for ('Test23::C', 0) in 'Test23::D' (7 entries).
+// CHECK-30-NEXT: 0 | vbase_offset (20)
+// CHECK-30-NEXT: 1 | vbase_offset (24)
+// CHECK-30-NEXT: 2 | offset_to_top (0)
+// CHECK-30-NEXT: 3 | Test23::C RTTI
+// CHECK-30-NEXT: -- (Test23::C, 0) vtable address --
+// CHECK-30-NEXT: 4 | vbase_offset (-4)
+// CHECK-30-NEXT: 5 | offset_to_top (-24)
+// CHECK-30-NEXT: 6 | Test23::C RTTI
+// CHECK-30-NEXT: -- (Test23::B, 24) vtable address --
+
+// CHECK-30: Construction vtable for ('Test23::B', 24) in 'Test23::D' (3 entries).
+// CHECK-30-NEXT: 0 | vbase_offset (-4)
+// CHECK-30-NEXT: 1 | offset_to_top (0)
+// CHECK-30-NEXT: 2 | Test23::B RTTI
+// CHECK-30-NEXT: -- (Test23::B, 24) vtable address --
+
+struct D : virtual A, virtual B, C {
+ int d;
+
+ void f();
+};
+void D::f() { }
+ D d;
+}
+
+namespace Test24 {
+
+// Another construction vtable test.
+
+struct A {
+ virtual void f();
+};
+
+struct B : virtual A { };
+struct C : virtual A { };
+
+// CHECK-31: Vtable for 'Test24::D' (10 entries).
+// CHECK-31-NEXT: 0 | vbase_offset (0)
+// CHECK-31-NEXT: 1 | vcall_offset (0)
+// CHECK-31-NEXT: 2 | offset_to_top (0)
+// CHECK-31-NEXT: 3 | Test24::D RTTI
+// CHECK-31-NEXT: -- (Test24::A, 0) vtable address --
+// CHECK-31-NEXT: -- (Test24::B, 0) vtable address --
+// CHECK-31-NEXT: -- (Test24::D, 0) vtable address --
+// CHECK-31-NEXT: 4 | void Test24::D::f()
+// CHECK-31-NEXT: 5 | vbase_offset (-8)
+// CHECK-31-NEXT: 6 | vcall_offset (-8)
+// CHECK-31-NEXT: 7 | offset_to_top (-8)
+// CHECK-31-NEXT: 8 | Test24::D RTTI
+// CHECK-31-NEXT: -- (Test24::C, 8) vtable address --
+// CHECK-31-NEXT: 9 | [unused] void Test24::D::f()
+//
+// CHECK-31: VTable indices for 'Test24::D' (1 entries).
+// CHECK-31-NEXT: 0 | void Test24::D::f()
+
+// CHECK-31: Construction vtable for ('Test24::B', 0) in 'Test24::D' (5 entries).
+// CHECK-31-NEXT: 0 | vbase_offset (0)
+// CHECK-31-NEXT: 1 | vcall_offset (0)
+// CHECK-31-NEXT: 2 | offset_to_top (0)
+// CHECK-31-NEXT: 3 | Test24::B RTTI
+// CHECK-31-NEXT: -- (Test24::A, 0) vtable address --
+// CHECK-31-NEXT: -- (Test24::B, 0) vtable address --
+// CHECK-31-NEXT: 4 | void Test24::A::f()
+
+// CHECK-31: Construction vtable for ('Test24::C', 8) in 'Test24::D' (9 entries).
+// CHECK-31-NEXT: 0 | vbase_offset (-8)
+// CHECK-31-NEXT: 1 | vcall_offset (-8)
+// CHECK-31-NEXT: 2 | offset_to_top (0)
+// CHECK-31-NEXT: 3 | Test24::C RTTI
+// CHECK-31-NEXT: -- (Test24::C, 8) vtable address --
+// CHECK-31-NEXT: 4 | [unused] void Test24::A::f()
+// CHECK-31-NEXT: 5 | vcall_offset (0)
+// CHECK-31-NEXT: 6 | offset_to_top (8)
+// CHECK-31-NEXT: 7 | Test24::C RTTI
+// CHECK-31-NEXT: -- (Test24::A, 0) vtable address --
+// CHECK-31-NEXT: 8 | void Test24::A::f()
+struct D : B, C {
+ virtual void f();
+};
+void D::f() { }
+
+}
+
+namespace Test25 {
+
+// This mainly tests that we don't assert on this class hierarchy.
+
+struct V {
+ virtual void f();
+};
+
+struct A : virtual V { };
+struct B : virtual V { };
+
+// CHECK-32: Vtable for 'Test25::C' (11 entries).
+// CHECK-32-NEXT: 0 | vbase_offset (0)
+// CHECK-32-NEXT: 1 | vcall_offset (0)
+// CHECK-32-NEXT: 2 | offset_to_top (0)
+// CHECK-32-NEXT: 3 | Test25::C RTTI
+// CHECK-32-NEXT: -- (Test25::A, 0) vtable address --
+// CHECK-32-NEXT: -- (Test25::C, 0) vtable address --
+// CHECK-32-NEXT: -- (Test25::V, 0) vtable address --
+// CHECK-32-NEXT: 4 | void Test25::V::f()
+// CHECK-32-NEXT: 5 | void Test25::C::g()
+// CHECK-32-NEXT: 6 | vbase_offset (-8)
+// CHECK-32-NEXT: 7 | vcall_offset (-8)
+// CHECK-32-NEXT: 8 | offset_to_top (-8)
+// CHECK-32-NEXT: 9 | Test25::C RTTI
+// CHECK-32-NEXT: -- (Test25::B, 8) vtable address --
+// CHECK-32-NEXT: 10 | [unused] void Test25::V::f()
+//
+// CHECK-32: VTable indices for 'Test25::C' (1 entries).
+// CHECK-32-NEXT: 1 | void Test25::C::g()
+
+// CHECK-32: Construction vtable for ('Test25::A', 0) in 'Test25::C' (5 entries).
+// CHECK-32-NEXT: 0 | vbase_offset (0)
+// CHECK-32-NEXT: 1 | vcall_offset (0)
+// CHECK-32-NEXT: 2 | offset_to_top (0)
+// CHECK-32-NEXT: 3 | Test25::A RTTI
+// CHECK-32-NEXT: -- (Test25::A, 0) vtable address --
+// CHECK-32-NEXT: -- (Test25::V, 0) vtable address --
+// CHECK-32-NEXT: 4 | void Test25::V::f()
+
+// CHECK-32: Construction vtable for ('Test25::B', 8) in 'Test25::C' (9 entries).
+// CHECK-32-NEXT: 0 | vbase_offset (-8)
+// CHECK-32-NEXT: 1 | vcall_offset (-8)
+// CHECK-32-NEXT: 2 | offset_to_top (0)
+// CHECK-32-NEXT: 3 | Test25::B RTTI
+// CHECK-32-NEXT: -- (Test25::B, 8) vtable address --
+// CHECK-32-NEXT: 4 | [unused] void Test25::V::f()
+// CHECK-32-NEXT: 5 | vcall_offset (0)
+// CHECK-32-NEXT: 6 | offset_to_top (8)
+// CHECK-32-NEXT: 7 | Test25::B RTTI
+// CHECK-32-NEXT: -- (Test25::V, 0) vtable address --
+// CHECK-32-NEXT: 8 | void Test25::V::f()
+struct C : A, virtual V, B {
+ virtual void g();
+};
+void C::g() { }
+
+}
+
+namespace Test26 {
+
+// Test that we generate the right number of entries in the C-in-D construction vtable, and that
+// we don't mark A::a as unused.
+
+struct A {
+ virtual void a();
+};
+
+struct B {
+ virtual void c();
+};
+
+struct C : virtual A {
+ virtual void b();
+};
+
+// CHECK-33: Vtable for 'Test26::D' (15 entries).
+// CHECK-33-NEXT: 0 | vbase_offset (8)
+// CHECK-33-NEXT: 1 | vbase_offset (8)
+// CHECK-33-NEXT: 2 | vbase_offset (0)
+// CHECK-33-NEXT: 3 | vcall_offset (0)
+// CHECK-33-NEXT: 4 | offset_to_top (0)
+// CHECK-33-NEXT: 5 | Test26::D RTTI
+// CHECK-33-NEXT: -- (Test26::B, 0) vtable address --
+// CHECK-33-NEXT: -- (Test26::D, 0) vtable address --
+// CHECK-33-NEXT: 6 | void Test26::B::c()
+// CHECK-33-NEXT: 7 | void Test26::D::d()
+// CHECK-33-NEXT: 8 | vcall_offset (0)
+// CHECK-33-NEXT: 9 | vbase_offset (0)
+// CHECK-33-NEXT: 10 | vcall_offset (0)
+// CHECK-33-NEXT: 11 | offset_to_top (-8)
+// CHECK-33-NEXT: 12 | Test26::D RTTI
+// CHECK-33-NEXT: -- (Test26::A, 8) vtable address --
+// CHECK-33-NEXT: -- (Test26::C, 8) vtable address --
+// CHECK-33-NEXT: 13 | void Test26::A::a()
+// CHECK-33-NEXT: 14 | void Test26::C::b()
+//
+// CHECK-33: VTable indices for 'Test26::D' (1 entries).
+// CHECK-33-NEXT: 1 | void Test26::D::d()
+
+// CHECK-33: Construction vtable for ('Test26::C', 8) in 'Test26::D' (7 entries).
+// CHECK-33-NEXT: 0 | vcall_offset (0)
+// CHECK-33-NEXT: 1 | vbase_offset (0)
+// CHECK-33-NEXT: 2 | vcall_offset (0)
+// CHECK-33-NEXT: 3 | offset_to_top (0)
+// CHECK-33-NEXT: 4 | Test26::C RTTI
+// CHECK-33-NEXT: -- (Test26::A, 8) vtable address --
+// CHECK-33-NEXT: -- (Test26::C, 8) vtable address --
+// CHECK-33-NEXT: 5 | void Test26::A::a()
+// CHECK-33-NEXT: 6 | void Test26::C::b()
+class D : virtual B, virtual C {
+ virtual void d();
+};
+void D::d() { }
+
+}
+
+namespace Test27 {
+
+// Test that we don't generate a secondary vtable for C in the D-in-E vtable, since
+// C doesn't have any virtual bases.
+
+struct A {
+ virtual void a();
+};
+
+struct B {
+ virtual void b();
+};
+
+struct C {
+ virtual void c();
+};
+
+struct D : A, virtual B, C {
+ virtual void d();
+};
+
+// CHECK-34: Vtable for 'Test27::E' (13 entries).
+// CHECK-34-NEXT: 0 | vbase_offset (16)
+// CHECK-34-NEXT: 1 | offset_to_top (0)
+// CHECK-34-NEXT: 2 | Test27::E RTTI
+// CHECK-34-NEXT: -- (Test27::A, 0) vtable address --
+// CHECK-34-NEXT: -- (Test27::D, 0) vtable address --
+// CHECK-34-NEXT: -- (Test27::E, 0) vtable address --
+// CHECK-34-NEXT: 3 | void Test27::A::a()
+// CHECK-34-NEXT: 4 | void Test27::D::d()
+// CHECK-34-NEXT: 5 | void Test27::E::e()
+// CHECK-34-NEXT: 6 | offset_to_top (-8)
+// CHECK-34-NEXT: 7 | Test27::E RTTI
+// CHECK-34-NEXT: -- (Test27::C, 8) vtable address --
+// CHECK-34-NEXT: 8 | void Test27::C::c()
+// CHECK-34-NEXT: 9 | vcall_offset (0)
+// CHECK-34-NEXT: 10 | offset_to_top (-16)
+// CHECK-34-NEXT: 11 | Test27::E RTTI
+// CHECK-34-NEXT: -- (Test27::B, 16) vtable address --
+// CHECK-34-NEXT: 12 | void Test27::B::b()
+//
+// CHECK-34: VTable indices for 'Test27::E' (1 entries).
+// CHECK-34-NEXT: 2 | void Test27::E::e()
+
+// CHECK-34: Construction vtable for ('Test27::D', 0) in 'Test27::E' (9 entries).
+// CHECK-34-NEXT: 0 | vbase_offset (16)
+// CHECK-34-NEXT: 1 | offset_to_top (0)
+// CHECK-34-NEXT: 2 | Test27::D RTTI
+// CHECK-34-NEXT: -- (Test27::A, 0) vtable address --
+// CHECK-34-NEXT: -- (Test27::D, 0) vtable address --
+// CHECK-34-NEXT: 3 | void Test27::A::a()
+// CHECK-34-NEXT: 4 | void Test27::D::d()
+// CHECK-34-NEXT: 5 | vcall_offset (0)
+// CHECK-34-NEXT: 6 | offset_to_top (-16)
+// CHECK-34-NEXT: 7 | Test27::D RTTI
+// CHECK-34-NEXT: -- (Test27::B, 16) vtable address --
+// CHECK-34-NEXT: 8 | void Test27::B::b()
+struct E : D {
+ virtual void e();
+};
+void E::e() { }
+
+}
+
+namespace Test28 {
+
+// Check that we do include the vtable for B in the D-in-E construction vtable, since
+// B is a base class of a virtual base (C).
+
+struct A {
+ virtual void a();
+};
+
+struct B {
+ virtual void b();
+};
+
+struct C : A, B {
+ virtual void c();
+};
+
+struct D : virtual C {
+};
+
+// CHECK-35: Vtable for 'Test28::E' (14 entries).
+// CHECK-35-NEXT: 0 | vbase_offset (8)
+// CHECK-35-NEXT: 1 | offset_to_top (0)
+// CHECK-35-NEXT: 2 | Test28::E RTTI
+// CHECK-35-NEXT: -- (Test28::D, 0) vtable address --
+// CHECK-35-NEXT: -- (Test28::E, 0) vtable address --
+// CHECK-35-NEXT: 3 | void Test28::E::e()
+// CHECK-35-NEXT: 4 | vcall_offset (8)
+// CHECK-35-NEXT: 5 | vcall_offset (0)
+// CHECK-35-NEXT: 6 | vcall_offset (0)
+// CHECK-35-NEXT: 7 | offset_to_top (-8)
+// CHECK-35-NEXT: 8 | Test28::E RTTI
+// CHECK-35-NEXT: -- (Test28::A, 8) vtable address --
+// CHECK-35-NEXT: -- (Test28::C, 8) vtable address --
+// CHECK-35-NEXT: 9 | void Test28::A::a()
+// CHECK-35-NEXT: 10 | void Test28::C::c()
+// CHECK-35-NEXT: 11 | offset_to_top (-16)
+// CHECK-35-NEXT: 12 | Test28::E RTTI
+// CHECK-35-NEXT: -- (Test28::B, 16) vtable address --
+// CHECK-35-NEXT: 13 | void Test28::B::b()
+//
+// CHECK-35: VTable indices for 'Test28::E' (1 entries).
+// CHECK-35-NEXT : 0 | void Test28::E::e()
+
+// CHECK-35: Construction vtable for ('Test28::D', 0) in 'Test28::E' (13 entries).
+// CHECK-35-NEXT: 0 | vbase_offset (8)
+// CHECK-35-NEXT: 1 | offset_to_top (0)
+// CHECK-35-NEXT: 2 | Test28::D RTTI
+// CHECK-35-NEXT: -- (Test28::D, 0) vtable address --
+// CHECK-35-NEXT: 3 | vcall_offset (8)
+// CHECK-35-NEXT: 4 | vcall_offset (0)
+// CHECK-35-NEXT: 5 | vcall_offset (0)
+// CHECK-35-NEXT: 6 | offset_to_top (-8)
+// CHECK-35-NEXT: 7 | Test28::D RTTI
+// CHECK-35-NEXT: -- (Test28::A, 8) vtable address --
+// CHECK-35-NEXT: -- (Test28::C, 8) vtable address --
+// CHECK-35-NEXT: 8 | void Test28::A::a()
+// CHECK-35-NEXT: 9 | void Test28::C::c()
+// CHECK-35-NEXT: 10 | offset_to_top (-16)
+// CHECK-35-NEXT: 11 | Test28::D RTTI
+// CHECK-35-NEXT: -- (Test28::B, 16) vtable address --
+// CHECK-35-NEXT: 12 | void Test28::B::b()
+struct E : D {
+ virtual void e();
+};
+void E::e() { }
+
+}
+
+namespace Test29 {
+
+// Test that the covariant return thunk for B::f will have a virtual 'this' adjustment,
+// matching gcc.
+
+struct V1 { };
+struct V2 : virtual V1 { };
+
+struct A {
+ virtual V1 *f();
+};
+
+// CHECK-36: Vtable for 'Test29::B' (6 entries).
+// CHECK-36-NEXT: 0 | vbase_offset (0)
+// CHECK-36-NEXT: 1 | vcall_offset (0)
+// CHECK-36-NEXT: 2 | offset_to_top (0)
+// CHECK-36-NEXT: 3 | Test29::B RTTI
+// CHECK-36-NEXT: -- (Test29::A, 0) vtable address --
+// CHECK-36-NEXT: -- (Test29::B, 0) vtable address --
+// CHECK-36-NEXT: 4 | Test29::V2 *Test29::B::f()
+// CHECK-36-NEXT: [return adjustment: 0 non-virtual, -24 vbase offset offset]
+// CHECK-36-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]
+// CHECK-36-NEXT: 5 | Test29::V2 *Test29::B::f()
+//
+// CHECK-36: VTable indices for 'Test29::B' (1 entries).
+// CHECK-36-NEXT: 1 | Test29::V2 *Test29::B::f()
+struct B : virtual A {
+ virtual V2 *f();
+};
+V2 *B::f() { return 0; }
+
+}
+
+namespace Test30 {
+
+// Test that we don't assert when generating a vtable for F.
+struct A { };
+
+struct B : virtual A {
+ int i;
+};
+
+struct C {
+ virtual void f();
+};
+
+struct D : virtual C, B { };
+struct E : virtual D { };
+
+struct F : E {
+ virtual void f();
+};
+void F::f() { }
+
+}
+
+namespace Test31 {
+
+// Test that we don't add D::f twice to the primary vtable.
+struct A {
+ int a;
+};
+
+struct B {
+ virtual void f();
+};
+
+struct C : A, virtual B {
+ virtual void f();
+};
+
+// CHECK-37: Vtable for 'Test31::D' (11 entries).
+// CHECK-37-NEXT: 0 | vbase_offset (0)
+// CHECK-37-NEXT: 1 | vbase_offset (8)
+// CHECK-37-NEXT: 2 | vcall_offset (0)
+// CHECK-37-NEXT: 3 | offset_to_top (0)
+// CHECK-37-NEXT: 4 | Test31::D RTTI
+// CHECK-37-NEXT: -- (Test31::B, 0) vtable address --
+// CHECK-37-NEXT: -- (Test31::D, 0) vtable address --
+// CHECK-37-NEXT: 5 | void Test31::D::f()
+// CHECK-37-NEXT: 6 | vbase_offset (-8)
+// CHECK-37-NEXT: 7 | vcall_offset (-8)
+// CHECK-37-NEXT: 8 | offset_to_top (-8)
+// CHECK-37-NEXT: 9 | Test31::D RTTI
+// CHECK-37-NEXT: -- (Test31::C, 8) vtable address --
+// CHECK-37-NEXT: 10 | void Test31::D::f()
+// CHECK-37-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]
+//
+// CHECK-37: VTable indices for 'Test31::D' (1 entries).
+// CHECK-37-NEXT: 0 | void Test31::D::f()
+struct D : virtual C {
+ virtual void f();
+};
+void D::f() { }
+
+}
+
+namespace Test32 {
+
+// Check that we correctly lay out the virtual bases of 'Test32::D'.
+
+struct A {
+ virtual void f();
+};
+
+struct B : virtual A { };
+struct C : A, virtual B { };
+struct D : virtual B { };
+
+// CHECK-38: Virtual base offset offsets for 'Test32::E' (3 entries).
+// CHECK-38-NEXT: Test32::A | -32
+// CHECK-38-NEXT: Test32::B | -24
+// CHECK-38-NEXT: Test32::D | -40
+struct E : C, virtual D {
+ virtual void f();
+};
+void E::f() { }
+
+}
+
+namespace Test33 {
+
+// Test that we don't emit too many vcall offsets in 'Test32::F'.
+
+struct A {
+ virtual void a();
+};
+
+struct B {
+ virtual void b();
+};
+
+struct C : virtual A, virtual B {
+ virtual void c();
+};
+
+struct D : virtual C { };
+
+struct E : A, D {
+ virtual void e();
+};
+
+// CHECK-39: Vtable for 'Test33::F' (30 entries).
+// CHECK-39-NEXT: 0 | vbase_offset (24)
+// CHECK-39-NEXT: 1 | vbase_offset (16)
+// CHECK-39-NEXT: 2 | vbase_offset (16)
+// CHECK-39-NEXT: 3 | vbase_offset (8)
+// CHECK-39-NEXT: 4 | offset_to_top (0)
+// CHECK-39-NEXT: 5 | Test33::F RTTI
+// CHECK-39-NEXT: -- (Test33::A, 0) vtable address --
+// CHECK-39-NEXT: -- (Test33::F, 0) vtable address --
+// CHECK-39-NEXT: 6 | void Test33::A::a()
+// CHECK-39-NEXT: 7 | void Test33::F::f()
+// CHECK-39-NEXT: 8 | vcall_offset (0)
+// CHECK-39-NEXT: 9 | vcall_offset (0)
+// CHECK-39-NEXT: 10 | vbase_offset (16)
+// CHECK-39-NEXT: 11 | vbase_offset (8)
+// CHECK-39-NEXT: 12 | vbase_offset (8)
+// CHECK-39-NEXT: 13 | offset_to_top (-8)
+// CHECK-39-NEXT: 14 | Test33::F RTTI
+// CHECK-39-NEXT: -- (Test33::A, 8) vtable address --
+// CHECK-39-NEXT: -- (Test33::E, 8) vtable address --
+// CHECK-39-NEXT: 15 | void Test33::A::a()
+// CHECK-39-NEXT: 16 | void Test33::E::e()
+// CHECK-39-NEXT: 17 | vbase_offset (0)
+// CHECK-39-NEXT: 18 | vcall_offset (0)
+// CHECK-39-NEXT: 19 | vbase_offset (8)
+// CHECK-39-NEXT: 20 | vbase_offset (0)
+// CHECK-39-NEXT: 21 | vcall_offset (0)
+// CHECK-39-NEXT: 22 | offset_to_top (-16)
+// CHECK-39-NEXT: 23 | Test33::F RTTI
+// CHECK-39-NEXT: -- (Test33::A, 16) vtable address --
+// CHECK-39-NEXT: -- (Test33::C, 16) vtable address --
+// CHECK-39-NEXT: -- (Test33::D, 16) vtable address --
+// CHECK-39-NEXT: 24 | void Test33::A::a()
+// CHECK-39-NEXT: 25 | void Test33::C::c()
+// CHECK-39-NEXT: 26 | vcall_offset (0)
+// CHECK-39-NEXT: 27 | offset_to_top (-24)
+// CHECK-39-NEXT: 28 | Test33::F RTTI
+// CHECK-39-NEXT: -- (Test33::B, 24) vtable address --
+// CHECK-39-NEXT: 29 | void Test33::B::b()
+//
+// CHECK-39: VTable indices for 'Test33::F' (1 entries).
+// CHECK-39-NEXT: 1 | void Test33::F::f()
+struct F : virtual E, A {
+ virtual void f();
+};
+void F::f() { }
+
+}
+
+namespace Test34 {
+
+// Test that we lay out the construction vtable for 'Test34::E' in 'Test34::F' correctly.
+
+struct A {
+ virtual void a();
+};
+struct B : virtual A { };
+
+struct C : B, A {
+ virtual void c();
+};
+
+struct D : A, C { };
+
+struct E : virtual D {
+ virtual void e();
+};
+
+// CHECK-40: Construction vtable for ('Test34::E', 0) in 'Test34::F' (22 entries).
+// CHECK-40-NEXT: 0 | vbase_offset (0)
+// CHECK-40-NEXT: 1 | vbase_offset (8)
+// CHECK-40-NEXT: 2 | vcall_offset (0)
+// CHECK-40-NEXT: 3 | offset_to_top (0)
+// CHECK-40-NEXT: 4 | Test34::E RTTI
+// CHECK-40-NEXT: -- (Test34::A, 0) vtable address --
+// CHECK-40-NEXT: -- (Test34::E, 0) vtable address --
+// CHECK-40-NEXT: 5 | void Test34::A::a()
+// CHECK-40-NEXT: 6 | void Test34::E::e()
+// CHECK-40-NEXT: 7 | vcall_offset (8)
+// CHECK-40-NEXT: 8 | vcall_offset (0)
+// CHECK-40-NEXT: 9 | vbase_offset (-8)
+// CHECK-40-NEXT: 10 | offset_to_top (-8)
+// CHECK-40-NEXT: 11 | Test34::E RTTI
+// CHECK-40-NEXT: -- (Test34::A, 8) vtable address --
+// CHECK-40-NEXT: -- (Test34::D, 8) vtable address --
+// CHECK-40-NEXT: 12 | void Test34::A::a()
+// CHECK-40-NEXT: 13 | vbase_offset (-16)
+// CHECK-40-NEXT: 14 | vcall_offset (-16)
+// CHECK-40-NEXT: 15 | offset_to_top (-16)
+// CHECK-40-NEXT: 16 | Test34::E RTTI
+// CHECK-40-NEXT: -- (Test34::B, 16) vtable address --
+// CHECK-40-NEXT: -- (Test34::C, 16) vtable address --
+// CHECK-40-NEXT: 17 | [unused] void Test34::A::a()
+// CHECK-40-NEXT: 18 | void Test34::C::c()
+// CHECK-40-NEXT: 19 | offset_to_top (-24)
+// CHECK-40-NEXT: 20 | Test34::E RTTI
+// CHECK-40-NEXT: -- (Test34::A, 24) vtable address --
+// CHECK-40-NEXT: 21 | void Test34::A::a()
+struct F : E {
+ virtual void f();
+};
+void F::f() { }
+
+}
+
+namespace Test35 {
+
+// Test that we lay out the virtual bases of 'Test35::H' in the correct order.
+
+struct A {
+ virtual void a();
+
+ int i;
+};
+
+struct B : virtual A {
+ virtual void b();
+};
+
+struct C {
+ virtual void c();
+};
+
+struct D : C, virtual B {
+ virtual void d();
+};
+
+struct E : D {
+ virtual void e();
+
+ bool b;
+};
+
+struct F : virtual D { };
+struct G : virtual E { };
+
+// CHECK-41: Vtable for 'Test35::H' (32 entries).
+// CHECK-41-NEXT: 0 | vbase_offset (32)
+// CHECK-41-NEXT: 1 | vbase_offset (0)
+// CHECK-41-NEXT: 2 | vcall_offset (0)
+// CHECK-41-NEXT: 3 | vcall_offset (0)
+// CHECK-41-NEXT: 4 | vbase_offset (16)
+// CHECK-41-NEXT: 5 | vbase_offset (8)
+// CHECK-41-NEXT: 6 | offset_to_top (0)
+// CHECK-41-NEXT: 7 | Test35::H RTTI
+// CHECK-41-NEXT: -- (Test35::C, 0) vtable address --
+// CHECK-41-NEXT: -- (Test35::D, 0) vtable address --
+// CHECK-41-NEXT: -- (Test35::F, 0) vtable address --
+// CHECK-41-NEXT: -- (Test35::H, 0) vtable address --
+// CHECK-41-NEXT: 8 | void Test35::C::c()
+// CHECK-41-NEXT: 9 | void Test35::D::d()
+// CHECK-41-NEXT: 10 | void Test35::H::h()
+// CHECK-41-NEXT: 11 | vbase_offset (0)
+// CHECK-41-NEXT: 12 | vbase_offset (24)
+// CHECK-41-NEXT: 13 | vcall_offset (0)
+// CHECK-41-NEXT: 14 | vbase_offset (8)
+// CHECK-41-NEXT: 15 | offset_to_top (-8)
+// CHECK-41-NEXT: 16 | Test35::H RTTI
+// CHECK-41-NEXT: -- (Test35::B, 8) vtable address --
+// CHECK-41-NEXT: -- (Test35::G, 8) vtable address --
+// CHECK-41-NEXT: 17 | void Test35::B::b()
+// CHECK-41-NEXT: 18 | vcall_offset (0)
+// CHECK-41-NEXT: 19 | offset_to_top (-16)
+// CHECK-41-NEXT: 20 | Test35::H RTTI
+// CHECK-41-NEXT: -- (Test35::A, 16) vtable address --
+// CHECK-41-NEXT: 21 | void Test35::A::a()
+// CHECK-41-NEXT: 22 | vcall_offset (0)
+// CHECK-41-NEXT: 23 | vcall_offset (0)
+// CHECK-41-NEXT: 24 | vcall_offset (0)
+// CHECK-41-NEXT: 25 | vbase_offset (-16)
+// CHECK-41-NEXT: 26 | vbase_offset (-24)
+// CHECK-41-NEXT: 27 | offset_to_top (-32)
+// CHECK-41-NEXT: 28 | Test35::H RTTI
+// CHECK-41-NEXT: -- (Test35::C, 32) vtable address --
+// CHECK-41-NEXT: -- (Test35::D, 32) vtable address --
+// CHECK-41-NEXT: -- (Test35::E, 32) vtable address --
+// CHECK-41-NEXT: 29 | void Test35::C::c()
+// CHECK-41-NEXT: 30 | void Test35::D::d()
+// CHECK-41-NEXT: 31 | void Test35::E::e()
+//
+// CHECK-41: Virtual base offset offsets for 'Test35::H' (4 entries).
+// CHECK-41-NEXT: Test35::A | -32
+// CHECK-41-NEXT: Test35::B | -24
+// CHECK-41-NEXT: Test35::D | -56
+// CHECK-41-NEXT: Test35::E | -64
+//
+// CHECK-41: VTable indices for 'Test35::H' (1 entries).
+// CHECK-41-NEXT: 2 | void Test35::H::h()
+struct H : F, G {
+ virtual void h();
+};
+void H::h() { }
+
+}
+
+namespace Test36 {
+
+// Test that we don't mark B::f as unused in the vtable for D.
+
+struct A {
+ virtual void f();
+};
+
+struct B : virtual A { };
+
+struct C : virtual A {
+ virtual void f();
+};
+
+// CHECK-42: Vtable for 'Test36::D' (12 entries).
+// CHECK-42-NEXT: 0 | vbase_offset (8)
+// CHECK-42-NEXT: 1 | vbase_offset (8)
+// CHECK-42-NEXT: 2 | vcall_offset (0)
+// CHECK-42-NEXT: 3 | offset_to_top (0)
+// CHECK-42-NEXT: 4 | Test36::D RTTI
+// CHECK-42-NEXT: -- (Test36::C, 0) vtable address --
+// CHECK-42-NEXT: -- (Test36::D, 0) vtable address --
+// CHECK-42-NEXT: 5 | void Test36::C::f()
+// CHECK-42-NEXT: 6 | void Test36::D::g()
+// CHECK-42-NEXT: 7 | vbase_offset (0)
+// CHECK-42-NEXT: 8 | vcall_offset (-8)
+// CHECK-42-NEXT: 9 | offset_to_top (-8)
+// CHECK-42-NEXT: 10 | Test36::D RTTI
+// CHECK-42-NEXT: -- (Test36::A, 8) vtable address --
+// CHECK-42-NEXT: -- (Test36::B, 8) vtable address --
+// CHECK-42-NEXT: 11 | void Test36::C::f()
+// CHECK-42-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]
+//
+// CHECK-42: VTable indices for 'Test36::D' (1 entries).
+// CHECK-42-NEXT: 1 | void Test36::D::g()
+struct D : virtual B, C {
+ virtual void g();
+};
+void D::g() { }
+
+}
+
+namespace Test37 {
+
+// Test that we give C::f the right vtable index. (PR9660).
+struct A {
+ virtual A* f() = 0;
+};
+
+struct B : virtual A {
+ virtual B* f();
+};
+
+// CHECK-43: VTable indices for 'Test37::C' (1 entries).
+// CHECK-43-NEXT: 1 | Test37::C *Test37::C::f()
+struct C : B {
+ virtual C* f();
+};
+
+C* C::f() { return 0; }
+
+}
+
+// rdar://problem/10959710
+namespace Test38 {
+ struct A {
+ virtual void *foo();
+ virtual const void *foo() const;
+ };
+
+ // CHECK-44: Vtable for 'Test38::B' (7 entries).
+ // CHECK-44-NEXT: 0 | vbase_offset (0)
+ // CHECK-44-NEXT: 1 | vcall_offset (0)
+ // CHECK-44-NEXT: 2 | vcall_offset (0)
+ // CHECK-44-NEXT: 3 | offset_to_top (0)
+ // CHECK-44-NEXT: 4 | Test38::B RTTI
+ // CHECK-44-NEXT: -- (Test38::A, 0) vtable address --
+ // CHECK-44-NEXT: -- (Test38::B, 0) vtable address --
+ // CHECK-44-NEXT: 5 | void *Test38::B::foo()
+ // CHECK-44-NEXT: 6 | const void *Test38::B::foo() const
+ //
+ // CHECK-44: VTable indices for 'Test38::B' (2 entries).
+ // CHECK-44-NEXT: 0 | void *Test38::B::foo()
+ // CHECK-44-NEXT: 1 | const void *Test38::B::foo() const
+ class B : virtual public A {
+ void *foo();
+ const void *foo() const;
+ };
+
+ void *B::foo() { return 0; }
+}
+
+namespace Test39 {
+ struct A {
+ virtual void foo() = delete;
+ };
+
+ // CHECK-45: Vtable for 'Test39::B' (4 entries).
+ // CHECK-45-NEXT: 0 | offset_to_top (0)
+ // CHECK-45-NEXT: 1 | Test39::B RTTI
+ // CHECK-45-NEXT: -- (Test39::A, 0) vtable address --
+ // CHECK-45-NEXT: -- (Test39::B, 0) vtable address --
+ // CHECK-45-NEXT: 2 | void Test39::A::foo() [deleted]
+ // CHECK-45-NEXT: 3 | void Test39::B::foo2()
+ //
+ // CHECK-45: VTable indices for 'Test39::B' (1 entries).
+ // CHECK-45-NEXT: 1 | void Test39::B::foo2()
+ struct B: A {
+ virtual void foo2();
+ };
+
+ void B::foo2() {
+ }
+}
+
+namespace Test40 {
+ struct A {
+ virtual void foo() = 0;
+ };
+
+ struct B : public A {
+ virtual void foo();
+ };
+
+ struct C: public B {
+ // CHECK-46: VTable indices for 'Test40::C' (8 entries).
+ // CHECK-46-NEXT: 1 | int Test40::C::f(int)
+ // CHECK-46-NEXT: 2 | int Test40::C::f()
+ // CHECK-46-NEXT: 3 | int Test40::C::g(int)
+ // CHECK-46-NEXT: 4 | int Test40::C::g()
+ // CHECK-46-NEXT: 5 | int Test40::C::h(int)
+ // CHECK-46-NEXT: 6 | int Test40::C::h()
+ // CHECK-46-NEXT: 7 | int Test40::C::i(int)
+ // CHECK-46-NEXT: 8 | int Test40::C::i()
+ virtual int f(int);
+ virtual int f();
+ virtual int g(int);
+ virtual int g();
+ virtual int h(int);
+ virtual int h();
+ virtual int i(int);
+ virtual int i();
+ };
+ // Force C's vtable to be generated.
+ int C::f() { return 1; }
+
+ class D : C {};
+
+ D d;
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/vtable-linkage.cpp b/src/llvm-project/clang/test/CodeGenCXX/vtable-linkage.cpp
new file mode 100644
index 0000000..d4f06ce
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/vtable-linkage.cpp
@@ -0,0 +1,217 @@
+// RUN: %clang_cc1 %s -triple=x86_64-pc-linux -emit-llvm -o %t
+// RUN: %clang_cc1 %s -triple=x86_64-pc-linux -emit-llvm -std=c++03 -o %t.03
+// RUN: %clang_cc1 %s -triple=x86_64-pc-linux -emit-llvm -std=c++11 -o %t.11
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -disable-llvm-passes -O3 -emit-llvm -o %t.opt
+// RUN: FileCheck %s < %t
+// RUN: FileCheck %s < %t.03
+// RUN: FileCheck %s < %t.11
+// RUN: FileCheck --check-prefix=CHECK-OPT %s < %t.opt
+
+namespace {
+ struct A {
+ virtual void f() { }
+ };
+}
+
+void f() { A b; }
+
+struct B {
+ B();
+ virtual void f();
+};
+
+B::B() { }
+
+struct C : virtual B {
+ C();
+ virtual void f() { }
+};
+
+C::C() { }
+
+struct D {
+ virtual void f();
+};
+
+void D::f() { }
+
+static struct : D { } e;
+
+// Force 'e' to be constructed and therefore have a vtable defined.
+void use_e() {
+ e.f();
+}
+
+// The destructor is the key function.
+template<typename T>
+struct E {
+ virtual ~E();
+};
+
+template<typename T> E<T>::~E() { }
+
+// Anchor is the key function
+template<>
+struct E<char> {
+ virtual void anchor();
+};
+
+void E<char>::anchor() { }
+
+template struct E<short>;
+extern template struct E<int>;
+
+void use_E() {
+ E<int> ei;
+ (void)ei;
+ E<long> el;
+ (void)el;
+}
+
+// No key function
+template<typename T>
+struct F {
+ virtual void foo() { }
+};
+
+// No key function
+template<>
+struct F<char> {
+ virtual void foo() { }
+};
+
+template struct F<short>;
+extern template struct F<int>;
+
+void use_F() {
+ F<char> fc;
+ fc.foo();
+ F<int> fi;
+ fi.foo();
+ F<long> fl;
+ (void)fl;
+}
+
+// B has a key function that is not defined in this translation unit so its vtable
+// has external linkage.
+// CHECK-DAG: @_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-DAG: @_ZTV1C = linkonce_odr unnamed_addr constant {{.*}}, comdat, align 8{{$}}
+// CHECK-DAG: @_ZTS1C = linkonce_odr constant {{.*}}, comdat, align 1{{$}}
+// CHECK-DAG: @_ZTI1C = linkonce_odr constant {{.*}}, comdat, align 8{{$}}
+// CHECK-DAG: @_ZTT1C = linkonce_odr unnamed_addr constant {{.*}}, comdat, align 8{{$}}
+
+// D has a key function that is defined in this translation unit so its vtable is
+// defined in the translation unit.
+// CHECK-DAG: @_ZTV1D = unnamed_addr constant
+// CHECK-DAG: @_ZTS1D = constant
+// CHECK-DAG: @_ZTI1D = constant
+
+// E<char> is an explicit specialization with a key function defined
+// in this translation unit, so its vtable should have external
+// linkage.
+// CHECK-DAG: @_ZTV1EIcE = unnamed_addr constant
+// CHECK-DAG: @_ZTS1EIcE = constant
+// CHECK-DAG: @_ZTI1EIcE = 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-DAG: @_ZTV1EIsE = weak_odr unnamed_addr constant {{.*}}, comdat,
+// CHECK-DAG: @_ZTS1EIsE = weak_odr constant {{.*}}, comdat, align 1{{$}}
+// CHECK-DAG: @_ZTI1EIsE = weak_odr constant {{.*}}, comdat, align 8{{$}}
+
+// F<short> is an explicit template instantiation without a key
+// function, so its vtable should have weak_odr linkage
+// CHECK-DAG: @_ZTV1FIsE = weak_odr unnamed_addr constant {{.*}}, comdat,
+// CHECK-DAG: @_ZTS1FIsE = weak_odr constant {{.*}}, comdat, align 1{{$}}
+// CHECK-DAG: @_ZTI1FIsE = weak_odr constant {{.*}}, comdat, align 8{{$}}
+
+// E<long> is an implicit template instantiation with a key function
+// defined in this translation unit, so its vtable should have
+// linkonce_odr linkage.
+// CHECK-DAG: @_ZTV1EIlE = linkonce_odr unnamed_addr constant {{.*}}, comdat,
+// CHECK-DAG: @_ZTS1EIlE = linkonce_odr constant {{.*}}, comdat, align 1{{$}}
+// CHECK-DAG: @_ZTI1EIlE = linkonce_odr constant {{.*}}, comdat, align 8{{$}}
+
+// F<long> is an implicit template instantiation with no key function,
+// so its vtable should have linkonce_odr linkage.
+// CHECK-DAG: @_ZTV1FIlE = linkonce_odr unnamed_addr constant {{.*}}, comdat,
+// CHECK-DAG: @_ZTS1FIlE = linkonce_odr constant {{.*}}, comdat, align 1{{$}}
+// CHECK-DAG: @_ZTI1FIlE = linkonce_odr constant {{.*}}, comdat, align 8{{$}}
+
+// F<int> is an explicit template instantiation declaration without a
+// key function, so its vtable should have external linkage.
+// CHECK-DAG: @_ZTV1FIiE = external unnamed_addr constant
+// CHECK-OPT-DAG: @_ZTV1FIiE = available_externally unnamed_addr constant
+
+// E<int> is an explicit template instantiation declaration. It has a
+// key function is not instantiated, so we know that vtable definition
+// will be generated in TU where key function will be defined
+// so we can mark it as external (without optimizations) and
+// available_externally (with optimizations) because all of the inline
+// virtual functions have been emitted.
+// CHECK-DAG: @_ZTV1EIiE = external unnamed_addr constant
+// CHECK-OPT-DAG: @_ZTV1EIiE = available_externally unnamed_addr constant
+
+// The anonymous struct for e has no linkage, so the vtable should have
+// internal linkage.
+// CHECK-DAG: @"_ZTV3$_0" = internal unnamed_addr constant
+// CHECK-DAG: @"_ZTS3$_0" = internal constant
+// CHECK-DAG: @"_ZTI3$_0" = internal constant
+
+// The A vtable should have internal linkage since it is inside an anonymous
+// namespace.
+// CHECK-DAG: @_ZTVN12_GLOBAL__N_11AE = internal unnamed_addr constant
+// CHECK-DAG: @_ZTSN12_GLOBAL__N_11AE = internal constant
+// CHECK-DAG: @_ZTIN12_GLOBAL__N_11AE = internal constant
+
+// F<char> is an explicit specialization without a key function, so
+// its vtable should have linkonce_odr linkage.
+// CHECK-DAG: @_ZTV1FIcE = linkonce_odr unnamed_addr constant {{.*}}, comdat,
+// CHECK-DAG: @_ZTS1FIcE = linkonce_odr constant {{.*}}, comdat, align 1{{$}}
+// CHECK-DAG: @_ZTI1FIcE = linkonce_odr constant {{.*}}, comdat, align 8{{$}}
+
+// CHECK-DAG: @_ZTV1GIiE = linkonce_odr unnamed_addr constant {{.*}}, comdat,
+template <typename T>
+class G {
+public:
+ G() {}
+ virtual void f0();
+ virtual void f1();
+};
+template <>
+void G<int>::f1() {}
+template <typename T>
+void G<T>::f0() {}
+void G_f0() { new G<int>(); }
+
+// H<int> has a key function without a body but it's a template instantiation
+// so its VTable must be emitted.
+// CHECK-DAG: @_ZTV1HIiE = linkonce_odr unnamed_addr constant {{.*}}, comdat,
+template <typename T>
+class H {
+public:
+ virtual ~H();
+};
+
+void use_H() {
+ H<int> h;
+}
+
+// I<int> has an explicit instantiation declaration and needs a VTT and
+// construction vtables.
+
+// CHECK-DAG: @_ZTV1IIiE = external unnamed_addr constant
+// CHECK-DAG: @_ZTT1IIiE = external unnamed_addr constant
+// CHECK-NOT: @_ZTC1IIiE
+//
+// CHECK-OPT-DAG: @_ZTV1IIiE = available_externally unnamed_addr constant
+// CHECK-OPT-DAG: @_ZTT1IIiE = available_externally unnamed_addr constant
+struct VBase1 { virtual void f(); }; struct VBase2 : virtual VBase1 {};
+template<typename T>
+struct I : VBase2 {};
+extern template struct I<int>;
+I<int> i;
diff --git a/src/llvm-project/clang/test/CodeGenCXX/vtable-pointer-initialization.cpp b/src/llvm-project/clang/test/CodeGenCXX/vtable-pointer-initialization.cpp
new file mode 100644
index 0000000..49c8de4
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/vtable-pointer-initialization.cpp
@@ -0,0 +1,60 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+struct Field {
+ Field();
+ ~Field();
+};
+
+struct Base {
+ Base();
+ ~Base();
+};
+
+struct A : Base {
+ A();
+ ~A();
+
+ virtual void f();
+
+ Field field;
+};
+
+// CHECK-LABEL: define void @_ZN1AC2Ev(%struct.A* %this) unnamed_addr
+// CHECK: call void @_ZN4BaseC2Ev(
+// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTV1A, i32 0, inrange i32 0, i32 2) to i32 (...)**)
+// CHECK: call void @_ZN5FieldC1Ev(
+// CHECK: ret void
+A::A() { }
+
+// CHECK-LABEL: define void @_ZN1AD2Ev(%struct.A* %this) unnamed_addr
+// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTV1A, i32 0, inrange i32 0, i32 2) to i32 (...)**)
+// CHECK: call void @_ZN5FieldD1Ev(
+// CHECK: call void @_ZN4BaseD2Ev(
+// CHECK: ret void
+A::~A() { }
+
+struct B : Base {
+ virtual void f();
+
+ Field field;
+};
+
+void f() { B b; }
+
+// CHECK-LABEL: define linkonce_odr void @_ZN1BC1Ev(%struct.B* %this) unnamed_addr
+// CHECK: call void @_ZN1BC2Ev(
+
+// CHECK-LABEL: define linkonce_odr void @_ZN1BD1Ev(%struct.B* %this) unnamed_addr
+// CHECK: call void @_ZN1BD2Ev(
+
+// CHECK-LABEL: define linkonce_odr void @_ZN1BC2Ev(%struct.B* %this) unnamed_addr
+// CHECK: call void @_ZN4BaseC2Ev(
+// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTV1B, i32 0, inrange i32 0, i32 2) to i32 (...)**)
+// CHECK: call void @_ZN5FieldC1Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define linkonce_odr void @_ZN1BD2Ev(%struct.B* %this) unnamed_addr
+// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTV1B, i32 0, inrange i32 0, i32 2) to i32 (...)**)
+// CHECK: call void @_ZN5FieldD1Ev(
+// CHECK: call void @_ZN4BaseD2Ev(
+// CHECK: ret void
diff --git a/src/llvm-project/clang/test/CodeGenCXX/vtt-layout.cpp b/src/llvm-project/clang/test/CodeGenCXX/vtt-layout.cpp
new file mode 100644
index 0000000..a5f7802
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/vtt-layout.cpp
@@ -0,0 +1,89 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -std=c++11 -emit-llvm -o - | FileCheck %s
+
+// Test1::B should just have a single entry in its VTT, which points to the vtable.
+namespace Test1 {
+struct A { };
+
+struct B : virtual A {
+ virtual void f();
+};
+
+void B::f() { }
+}
+
+// Check that we don't add a secondary virtual pointer for Test2::A, since Test2::A doesn't have any virtual member functions or bases.
+namespace Test2 {
+ struct A { };
+
+ struct B : A { virtual void f(); };
+ struct C : virtual B { };
+
+ C c;
+}
+
+// This is the sample from the C++ Itanium ABI, p2.6.2.
+namespace Test3 {
+ class A1 { int i; };
+ class A2 { int i; virtual void f(); };
+ class V1 : public A1, public A2 { int i; };
+ class B1 { int i; };
+ class B2 { int i; };
+ class V2 : public B1, public B2, public virtual V1 { int i; };
+ class V3 {virtual void g(); };
+ class C1 : public virtual V1 { int i; };
+ class C2 : public virtual V3, virtual V2 { int i; };
+ class X1 { int i; };
+ class C3 : public X1 { int i; };
+ class D : public C1, public C2, public C3 { int i; };
+
+ D d;
+}
+
+// This is the sample from the C++ Itanium ABI, p2.6.2, with the change suggested
+// (making A2 a virtual base of V1)
+namespace Test4 {
+ class A1 { int i; };
+ class A2 { int i; virtual void f(); };
+ class V1 : public A1, public virtual A2 { int i; };
+ class B1 { int i; };
+ class B2 { int i; };
+ class V2 : public B1, public B2, public virtual V1 { int i; };
+ class V3 {virtual void g(); };
+ class C1 : public virtual V1 { int i; };
+ class C2 : public virtual V3, virtual V2 { int i; };
+ class X1 { int i; };
+ class C3 : public X1 { int i; };
+ class D : public C1, public C2, public C3 { int i; };
+
+ D d;
+}
+
+namespace Test5 {
+ struct A {
+ virtual void f() = 0;
+ virtual void anchor();
+ };
+
+ void A::anchor() {
+ }
+}
+
+namespace Test6 {
+ struct A {
+ virtual void f() = delete;
+ virtual void anchor();
+ };
+
+ void A::anchor() {
+ }
+}
+
+// CHECK: @_ZTTN5Test11BE = unnamed_addr constant [1 x i8*] [i8* bitcast (i8** getelementptr inbounds ({ [4 x i8*] }, { [4 x i8*] }* @_ZTVN5Test11BE, i32 0, inrange i32 0, i32 3) to i8*)]
+// CHECK: @_ZTVN5Test51AE = unnamed_addr constant { [4 x i8*] } { [4 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTIN5Test51AE to i8*), i8* bitcast (void ()* @__cxa_pure_virtual to i8*), i8* bitcast (void (%"struct.Test5::A"*)* @_ZN5Test51A6anchorEv to i8*)] }
+// CHECK: @_ZTVN5Test61AE = unnamed_addr constant { [4 x i8*] } { [4 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTIN5Test61AE to i8*), i8* bitcast (void ()* @__cxa_deleted_virtual to i8*), i8* bitcast (void (%"struct.Test6::A"*)* @_ZN5Test61A6anchorEv to i8*)] }
+// CHECK: @_ZTTN5Test21CE = linkonce_odr unnamed_addr constant [2 x i8*] [i8* bitcast (i8** getelementptr inbounds ({ [5 x i8*] }, { [5 x i8*] }* @_ZTVN5Test21CE, i32 0, inrange i32 0, i32 4) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [5 x i8*] }, { [5 x i8*] }* @_ZTVN5Test21CE, i32 0, inrange i32 0, i32 4) to i8*)]
+// CHECK: @_ZTTN5Test31DE = linkonce_odr unnamed_addr constant [13 x i8*] [i8* bitcast (i8** getelementptr inbounds ({ [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }, { [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }* @_ZTVN5Test31DE, i32 0, inrange i32 0, i32 5) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [3 x i8*], [4 x i8*] }, { [3 x i8*], [4 x i8*] }* @_ZTCN5Test31DE0_NS_2C1E, i32 0, inrange i32 0, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [3 x i8*], [4 x i8*] }, { [3 x i8*], [4 x i8*] }* @_ZTCN5Test31DE0_NS_2C1E, i32 0, inrange i32 1, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [7 x i8*], [3 x i8*], [4 x i8*] }, { [7 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test31DE16_NS_2C2E, i32 0, inrange i32 0, i32 6) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [7 x i8*], [3 x i8*], [4 x i8*] }, { [7 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test31DE16_NS_2C2E, i32 0, inrange i32 0, i32 6) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [7 x i8*], [3 x i8*], [4 x i8*] }, { [7 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test31DE16_NS_2C2E, i32 0, inrange i32 1, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [7 x i8*], [3 x i8*], [4 x i8*] }, { [7 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test31DE16_NS_2C2E, i32 0, inrange i32 2, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }, { [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }* @_ZTVN5Test31DE, i32 0, inrange i32 2, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }, { [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }* @_ZTVN5Test31DE, i32 0, inrange i32 1, i32 6) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }, { [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }* @_ZTVN5Test31DE, i32 0, inrange i32 1, i32 6) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }, { [5 x i8*], [7 x i8*], [4 x i8*], [3 x i8*] }* @_ZTVN5Test31DE, i32 0, inrange i32 3, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [3 x i8*], [4 x i8*] }, { [3 x i8*], [4 x i8*] }* @_ZTCN5Test31DE64_NS_2V2E, i32 0, inrange i32 0, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [3 x i8*], [4 x i8*] }, { [3 x i8*], [4 x i8*] }* @_ZTCN5Test31DE64_NS_2V2E, i32 0, inrange i32 1, i32 3) to i8*)]
+// CHECK: @_ZTVN5Test41DE = linkonce_odr unnamed_addr constant { [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] } { [6 x i8*] [i8* inttoptr (i64 72 to i8*), i8* inttoptr (i64 16 to i8*), i8* inttoptr (i64 56 to i8*), i8* inttoptr (i64 40 to i8*), i8* null, i8* bitcast ({ i8*, i8*, i32, i32, i8*, i64, i8*, i64, i8*, i64 }* @_ZTIN5Test41DE to i8*)], [8 x i8*] [i8* inttoptr (i64 40 to i8*), i8* inttoptr (i64 24 to i8*), i8* inttoptr (i64 56 to i8*), i8* null, i8* null, i8* inttoptr (i64 -16 to i8*), i8* bitcast ({ i8*, i8*, i32, i32, i8*, i64, i8*, i64, i8*, i64 }* @_ZTIN5Test41DE to i8*), i8* bitcast (void (%"class.Test4::V3"*)* @_ZN5Test42V31gEv to i8*)], [3 x i8*] [i8* inttoptr (i64 16 to i8*), i8* inttoptr (i64 -40 to i8*), i8* bitcast ({ i8*, i8*, i32, i32, i8*, i64, i8*, i64, i8*, i64 }* @_ZTIN5Test41DE to i8*)], [4 x i8*] [i8* null, i8* inttoptr (i64 -56 to i8*), i8* bitcast ({ i8*, i8*, i32, i32, i8*, i64, i8*, i64, i8*, i64 }* @_ZTIN5Test41DE to i8*), i8* bitcast (void (%"class.Test4::A2"*)* @_ZN5Test42A21fEv to i8*)], [4 x i8*] [i8* inttoptr (i64 -16 to i8*), i8* inttoptr (i64 -32 to i8*), i8* inttoptr (i64 -72 to i8*), i8* bitcast ({ i8*, i8*, i32, i32, i8*, i64, i8*, i64, i8*, i64 }* @_ZTIN5Test41DE to i8*)] }
+// CHECK: @_ZTTN5Test41DE = linkonce_odr unnamed_addr constant [19 x i8*] [i8* bitcast (i8** getelementptr inbounds ({ [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }, { [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }* @_ZTVN5Test41DE, i32 0, inrange i32 0, i32 6) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [4 x i8*], [3 x i8*], [4 x i8*] }, { [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE0_NS_2C1E, i32 0, inrange i32 0, i32 4) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [4 x i8*], [3 x i8*], [4 x i8*] }, { [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE0_NS_2C1E, i32 0, inrange i32 1, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [4 x i8*], [3 x i8*], [4 x i8*] }, { [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE0_NS_2C1E, i32 0, inrange i32 2, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }, { [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE16_NS_2C2E, i32 0, inrange i32 0, i32 7) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }, { [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE16_NS_2C2E, i32 0, inrange i32 0, i32 7) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }, { [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE16_NS_2C2E, i32 0, inrange i32 1, i32 4) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }, { [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE16_NS_2C2E, i32 0, inrange i32 2, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }, { [8 x i8*], [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE16_NS_2C2E, i32 0, inrange i32 3, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }, { [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }* @_ZTVN5Test41DE, i32 0, inrange i32 2, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }, { [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }* @_ZTVN5Test41DE, i32 0, inrange i32 3, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }, { [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }* @_ZTVN5Test41DE, i32 0, inrange i32 1, i32 7) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }, { [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }* @_ZTVN5Test41DE, i32 0, inrange i32 1, i32 7) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }, { [6 x i8*], [8 x i8*], [3 x i8*], [4 x i8*], [4 x i8*] }* @_ZTVN5Test41DE, i32 0, inrange i32 4, i32 4) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [3 x i8*], [4 x i8*] }, { [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE40_NS_2V1E, i32 0, inrange i32 0, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [3 x i8*], [4 x i8*] }, { [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE40_NS_2V1E, i32 0, inrange i32 1, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [4 x i8*], [3 x i8*], [4 x i8*] }, { [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE72_NS_2V2E, i32 0, inrange i32 0, i32 4) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [4 x i8*], [3 x i8*], [4 x i8*] }, { [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE72_NS_2V2E, i32 0, inrange i32 1, i32 3) to i8*), i8* bitcast (i8** getelementptr inbounds ({ [4 x i8*], [3 x i8*], [4 x i8*] }, { [4 x i8*], [3 x i8*], [4 x i8*] }* @_ZTCN5Test41DE72_NS_2V2E, i32 0, inrange i32 2, i32 3) to i8*)]
+// CHECK: declare void @__cxa_pure_virtual() unnamed_addr
+// CHECK: declare void @__cxa_deleted_virtual() unnamed_addr
diff --git a/src/llvm-project/clang/test/CodeGenCXX/warn-padded-packed.cpp b/src/llvm-project/clang/test/CodeGenCXX/warn-padded-packed.cpp
new file mode 100644
index 0000000..2cb0495
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/warn-padded-packed.cpp
@@ -0,0 +1,153 @@
+// 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;
+ 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 {
+ int x;
+ int y;
+} __attribute__((packed));
+
+struct S10 {
+ int x;
+ char a,b,c,d;
+} __attribute__((packed));
+
+
+struct S11 { // expected-warning {{packed attribute is unnecessary for '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;
+};
+
+struct S14 { // expected-warning {{packed attribute is unnecessary for 'S14'}}
+ char a,b,c,d;
+} __attribute__((packed));
+
+struct S15 { // expected-warning {{packed attribute is unnecessary for 'S15'}}
+ struct S14 s;
+ char a;
+} __attribute__((packed));
+
+struct S16 { // expected-warning {{padding size of 'S16' with 2 bytes to alignment boundary}} expected-warning {{packed attribute is unnecessary for 'S16'}}
+ char a,b;
+} __attribute__((packed, aligned(4)));
+
+struct S17 {
+ struct S16 s;
+ char a,b;
+} __attribute__((packed, aligned(2)));
+
+struct S18 { // expected-warning {{padding size of 'S18' with 2 bytes to alignment boundary}} expected-warning {{packed attribute is unnecessary for 'S18'}}
+ struct S16 s;
+ char a,b;
+} __attribute__((packed, aligned(4)));
+
+struct S19 { // expected-warning {{packed attribute is unnecessary for 'S19'}}
+ bool b;
+ char a;
+} __attribute__((packed, aligned(1)));
+
+struct S20 {
+ int i;
+ char a;
+} __attribute__((packed, aligned(1)));
+
+struct S21 { // expected-warning {{padding size of 'S21' with 4 bits to alignment boundary}}
+ unsigned char a : 6;
+ unsigned char b : 6;
+} __attribute__((packed, aligned(1)));
+
+struct S22 { // expected-warning {{packed attribute is unnecessary for 'S22'}}
+ unsigned char a : 4;
+ unsigned char b : 4;
+} __attribute__((packed));
+
+struct S23 { // expected-warning {{padding size of 'S23' with 4 bits to alignment boundary}} expected-warning {{packed attribute is unnecessary for 'S23'}}
+ unsigned char a : 2;
+ unsigned char b : 2;
+} __attribute__((packed));
+
+struct S24 {
+ unsigned char a : 6;
+ unsigned char b : 6;
+ unsigned char c : 6;
+ unsigned char d : 6;
+ unsigned char e : 6;
+ unsigned char f : 6;
+ unsigned char g : 6;
+ unsigned char h : 6;
+} __attribute__((packed));
+
+struct S25 { // expected-warning {{padding size of 'S25' with 7 bits to alignment boundary}} expected-warning {{packed attribute is unnecessary for 'S25'}}
+ unsigned char a;
+ unsigned char b : 1;
+} __attribute__((packed));
+
+struct S26 { // expected-warning {{packed attribute is unnecessary for 'S26'}}
+ unsigned char a : 1;
+ unsigned char b; //expected-warning {{padding struct 'S26' with 7 bits to align 'b'}}
+} __attribute__((packed));
+
+struct S27 { // expected-warning {{padding size of 'S27' with 7 bits to alignment boundary}}
+ unsigned char a : 1;
+ unsigned char b : 8;
+} __attribute__((packed));
+
+
+// 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*,
+ S14*, S15*, S16*, S17*, S18*, S19*, S20*, S21*, S22*, S23*, S24*, S25*,
+ S26*, S27*){}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/wasm-args-returns.cpp b/src/llvm-project/clang/test/CodeGenCXX/wasm-args-returns.cpp
new file mode 100644
index 0000000..a7c4e1e
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/wasm-args-returns.cpp
@@ -0,0 +1,104 @@
+// RUN: %clang_cc1 -O1 -triple wasm32-unknown-unknown -emit-llvm -o - %s \
+// RUN: | FileCheck %s
+// RUN: %clang_cc1 -O1 -triple wasm64-unknown-unknown -emit-llvm -o - %s \
+// RUN: | FileCheck %s
+
+#define concat_(x, y) x##y
+#define concat(x, y) concat_(x, y)
+
+#define test(T) \
+ T forward(T x) { return x; } \
+ void use(T x); \
+ T concat(def_, T)(void); \
+ void concat(test_, T)(void) { use(concat(def_, T)()); }
+
+struct one_field {
+ double d;
+};
+test(one_field);
+// CHECK: define double @_Z7forward9one_field(double returned %{{.*}})
+//
+// CHECK: define void @_Z14test_one_fieldv()
+// CHECK: %[[call:.*]] = tail call double @_Z13def_one_fieldv()
+// CHECK: tail call void @_Z3use9one_field(double %[[call]])
+// CHECK: ret void
+//
+// CHECK: declare void @_Z3use9one_field(double)
+// CHECK: declare double @_Z13def_one_fieldv()
+
+struct two_fields {
+ double d, e;
+};
+test(two_fields);
+// CHECK: define void @_Z7forward10two_fields(%struct.two_fields* noalias nocapture sret %{{.*}}, %struct.two_fields* byval nocapture readonly align 8 %{{.*}})
+//
+// CHECK: define void @_Z15test_two_fieldsv()
+// CHECK: %[[tmp:.*]] = alloca %struct.two_fields, align 8
+// CHECK: call void @_Z14def_two_fieldsv(%struct.two_fields* nonnull sret %[[tmp]])
+// CHECK: call void @_Z3use10two_fields(%struct.two_fields* byval nonnull align 8 %[[tmp]])
+// CHECK: ret void
+//
+// CHECK: declare void @_Z3use10two_fields(%struct.two_fields* byval align 8)
+// CHECK: declare void @_Z14def_two_fieldsv(%struct.two_fields* sret)
+
+struct copy_ctor {
+ double d;
+ copy_ctor(copy_ctor const &);
+};
+test(copy_ctor);
+// CHECK: define void @_Z7forward9copy_ctor(%struct.copy_ctor* noalias sret %{{.*}}, %struct.copy_ctor* %{{.*}})
+//
+// CHECK: declare %struct.copy_ctor* @_ZN9copy_ctorC1ERKS_(%struct.copy_ctor* returned, %struct.copy_ctor* dereferenceable(8))
+//
+// CHECK: define void @_Z14test_copy_ctorv()
+// CHECK: %[[tmp:.*]] = alloca %struct.copy_ctor, align 8
+// CHECK: call void @_Z13def_copy_ctorv(%struct.copy_ctor* nonnull sret %[[tmp]])
+// CHECK: call void @_Z3use9copy_ctor(%struct.copy_ctor* nonnull %[[tmp]])
+// CHECK: ret void
+//
+// CHECK: declare void @_Z3use9copy_ctor(%struct.copy_ctor*)
+// CHECK: declare void @_Z13def_copy_ctorv(%struct.copy_ctor* sret)
+
+struct __attribute__((aligned(16))) aligned_copy_ctor {
+ double d, e;
+ aligned_copy_ctor(aligned_copy_ctor const &);
+};
+test(aligned_copy_ctor);
+// CHECK: define void @_Z7forward17aligned_copy_ctor(%struct.aligned_copy_ctor* noalias sret %{{.*}}, %struct.aligned_copy_ctor* %{{.*}})
+//
+// CHECK: declare %struct.aligned_copy_ctor* @_ZN17aligned_copy_ctorC1ERKS_(%struct.aligned_copy_ctor* returned, %struct.aligned_copy_ctor* dereferenceable(16))
+//
+// CHECK: define void @_Z22test_aligned_copy_ctorv()
+// CHECK: %[[tmp:.*]] = alloca %struct.aligned_copy_ctor, align 16
+// CHECK: call void @_Z21def_aligned_copy_ctorv(%struct.aligned_copy_ctor* nonnull sret %[[tmp]])
+// CHECK: call void @_Z3use17aligned_copy_ctor(%struct.aligned_copy_ctor* nonnull %[[tmp]])
+// CHECK: ret void
+//
+// CHECK: declare void @_Z3use17aligned_copy_ctor(%struct.aligned_copy_ctor*)
+// CHECK: declare void @_Z21def_aligned_copy_ctorv(%struct.aligned_copy_ctor* sret)
+
+struct empty {};
+test(empty);
+// CHECK: define void @_Z7forward5empty()
+//
+// CHECK: define void @_Z10test_emptyv()
+// CHECK: tail call void @_Z9def_emptyv()
+// CHECK: tail call void @_Z3use5empty()
+// CHECK: ret void
+//
+// CHECK: declare void @_Z3use5empty()
+// CHECK: declare void @_Z9def_emptyv()
+
+struct one_bitfield {
+ int d : 3;
+};
+test(one_bitfield);
+// CHECK: define i32 @_Z7forward12one_bitfield(i32 returned %{{.*}})
+//
+// CHECK: define void @_Z17test_one_bitfieldv()
+// CHECK: %[[call:.*]] = tail call i32 @_Z16def_one_bitfieldv()
+// CHECK: tail call void @_Z3use12one_bitfield(i32 %[[call]])
+// CHECK: ret void
+//
+// CHECK: declare void @_Z3use12one_bitfield(i32)
+// CHECK: declare i32 @_Z16def_one_bitfieldv()
diff --git a/src/llvm-project/clang/test/CodeGenCXX/wasm-eh.cpp b/src/llvm-project/clang/test/CodeGenCXX/wasm-eh.cpp
new file mode 100644
index 0000000..ea77fec
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/wasm-eh.cpp
@@ -0,0 +1,384 @@
+// RUN: %clang_cc1 %s -triple wasm32-unknown-unknown -fms-extensions -fexceptions -fcxx-exceptions -target-feature +exception-handling -emit-llvm -o - -std=c++11 | FileCheck %s
+// RUN: %clang_cc1 %s -triple wasm64-unknown-unknown -fms-extensions -fexceptions -fcxx-exceptions -target-feature +exception-handling -emit-llvm -o - -std=c++11 | FileCheck %s
+
+void may_throw();
+void dont_throw() noexcept;
+
+struct Cleanup {
+ ~Cleanup() { dont_throw(); }
+};
+
+// Multiple catch clauses w/o catch-all
+void test0() {
+ try {
+ may_throw();
+ } catch (int) {
+ dont_throw();
+ } catch (double) {
+ dont_throw();
+ }
+}
+
+// CHECK-LABEL: define void @_Z5test0v() {{.*}} personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*)
+
+// CHECK: %[[INT_ALLOCA:.*]] = alloca i32
+// CHECK: invoke void @_Z9may_throwv()
+// CHECK-NEXT: to label %[[NORMAL_BB:.*]] unwind label %[[CATCHDISPATCH_BB:.*]]
+
+// CHECK: [[CATCHDISPATCH_BB]]:
+// CHECK-NEXT: %[[CATCHSWITCH:.*]] = catchswitch within none [label %[[CATCHSTART_BB:.*]]] unwind to caller
+
+// CHECK: [[CATCHSTART_BB]]:
+// CHECK-NEXT: %[[CATCHPAD:.*]] = catchpad within %[[CATCHSWITCH]] [i8* bitcast (i8** @_ZTIi to i8*), i8* bitcast (i8** @_ZTId to i8*)]
+// CHECK-NEXT: %[[EXN:.*]] = call i8* @llvm.wasm.get.exception(token %[[CATCHPAD]])
+// CHECK-NEXT: store i8* %[[EXN]], i8** %exn.slot
+// CHECK-NEXT: %[[SELECTOR:.*]] = call i32 @llvm.wasm.get.ehselector(token %[[CATCHPAD]])
+// CHECK-NEXT: %[[TYPEID:.*]] = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) #2
+// CHECK-NEXT: %[[MATCHES:.*]] = icmp eq i32 %[[SELECTOR]], %[[TYPEID]]
+// CHECK-NEXT: br i1 %[[MATCHES]], label %[[CATCH_INT_BB:.*]], label %[[CATCH_FALLTHROUGH_BB:.*]]
+
+// CHECK: [[CATCH_INT_BB]]:
+// CHECK-NEXT: %[[EXN:.*]] = load i8*, i8** %exn.slot
+// CHECK-NEXT: %[[ADDR:.*]] = call i8* @__cxa_begin_catch(i8* %[[EXN]]) {{.*}} [ "funclet"(token %[[CATCHPAD]]) ]
+// CHECK-NEXT: %[[ADDR_CAST:.*]] = bitcast i8* %[[ADDR]] to i32*
+// CHECK-NEXT: %[[INT_VAL:.*]] = load i32, i32* %[[ADDR_CAST]]
+// CHECK-NEXT: store i32 %[[INT_VAL]], i32* %[[INT_ALLOCA]]
+// CHECK-NEXT: call void @_Z10dont_throwv() {{.*}} [ "funclet"(token %[[CATCHPAD]]) ]
+// CHECK-NEXT: call void @__cxa_end_catch() {{.*}} [ "funclet"(token %[[CATCHPAD]]) ]
+// CHECK-NEXT: catchret from %[[CATCHPAD]] to label %[[CATCHRET_DEST_BB0:.*]]
+
+// CHECK: [[CATCHRET_DEST_BB0]]:
+// CHECK-NEXT: br label %[[TRY_CONT_BB:.*]]
+
+// CHECK: [[CATCH_FALLTHROUGH_BB]]
+// CHECK-NEXT: %[[TYPEID:.*]] = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTId to i8*)) #2
+// CHECK-NEXT: %[[MATCHES:.*]] = icmp eq i32 %[[SELECTOR]], %[[TYPEID]]
+// CHECK-NEXT: br i1 %[[MATCHES]], label %[[CATCH_FLOAT_BB:.*]], label %[[RETHROW_BB:.*]]
+
+// CHECK: [[CATCH_FLOAT_BB]]:
+// CHECK: catchret from %[[CATCHPAD]] to label %[[CATCHRET_DEST_BB1:.*]]
+
+// CHECK: [[CATCHRET_DEST_BB1]]:
+// CHECK-NEXT: br label %[[TRY_CONT_BB]]
+
+// CHECK: [[RETHROW_BB]]:
+// CHECK-NEXT: call void @__cxa_rethrow() {{.*}} [ "funclet"(token %[[CATCHPAD]]) ]
+// CHECK-NEXT: unreachable
+
+// Single catch-all
+void test1() {
+ try {
+ may_throw();
+ } catch (...) {
+ dont_throw();
+ }
+}
+
+// CATCH-LABEL: @_Z5test1v()
+
+// CHECK: %[[CATCHSWITCH:.*]] = catchswitch within none [label %[[CATCHSTART_BB:.*]]] unwind to caller
+
+// CHECK: [[CATCHSTART_BB]]:
+// CHECK-NEXT: %[[CATCHPAD:.*]] = catchpad within %[[CATCHSWITCH]] [i8* null]
+// CHECK: br label %[[CATCH_ALL_BB:.*]]
+
+// CHECK: [[CATCH_ALL_BB]]:
+// CHECK: catchret from %[[CATCHPAD]] to label
+
+// Multiple catch clauses w/ catch-all
+void test2() {
+ try {
+ may_throw();
+ } catch (int) {
+ dont_throw();
+ } catch (...) {
+ dont_throw();
+ }
+}
+
+// CHECK-LABEL: @_Z5test2v()
+
+// CHECK: %[[CATCHSWITCH:.*]] = catchswitch within none [label %[[CATCHSTART_BB:.*]]] unwind to caller
+
+// CHECK: [[CATCHSTART_BB]]:
+// CHECK-NEXT: %[[CATCHPAD:.*]] = catchpad within %[[CATCHSWITCH]] [i8* bitcast (i8** @_ZTIi to i8*), i8* null]
+// CHECK: br i1 %{{.*}}, label %[[CATCH_INT_BB:.*]], label %[[CATCH_ALL_BB:.*]]
+
+// CHECK: [[CATCH_INT_BB]]:
+// CHECK: catchret from %[[CATCHPAD]] to label
+
+// CHECK: [[CATCH_ALL_BB]]:
+// CHECK: catchret from %[[CATCHPAD]] to label
+
+// Cleanup
+void test3() {
+ Cleanup c;
+ may_throw();
+}
+
+// CHECK-LABEL: @_Z5test3v()
+
+// CHECK: invoke void @_Z9may_throwv()
+// CHECK-NEXT: to label {{.*}} unwind label %[[EHCLEANUP_BB:.*]]
+
+// CHECK: [[EHCLEANUP_BB]]:
+// CHECK-NEXT: %[[CLEANUPPAD:.*]] = cleanuppad within none []
+// CHECK-NEXT: call %struct.Cleanup* @_ZN7CleanupD1Ev(%struct.Cleanup* %{{.*}}) {{.*}} [ "funclet"(token %[[CLEANUPPAD]]) ]
+// CHECK-NEXT: cleanupret from %[[CLEANUPPAD]] unwind to caller
+
+// Possibly throwing function call within a catch
+void test4() {
+ try {
+ may_throw();
+ } catch (int) {
+ may_throw();
+ }
+}
+
+// CHECK-LABEL: @_Z5test4v()
+
+// CHECK: %[[CATCHSWITCH]] = catchswitch within none [label %[[CATCHSTART_BB]]] unwind to caller
+
+// CHECK: [[CATCHSTART_BB]]:
+// CHECK: %[[CATCHPAD:.*]] = catchpad within %[[CATCHSWITCH]] [i8* bitcast (i8** @_ZTIi to i8*)]
+
+// CHECK: invoke void @_Z9may_throwv() [ "funclet"(token %[[CATCHPAD]]) ]
+// CHECK-NEXT: to label %[[INVOKE_CONT_BB:.*]] unwind label %[[EHCLEANUP_BB:.*]]
+
+// CHECK: [[INVOKE_CONT_BB]]:
+// CHECK-NEXT: call void @__cxa_end_catch() {{.*}} [ "funclet"(token %[[CATCHPAD]]) ]
+// CHECK-NEXT: catchret from %[[CATCHPAD]] to label
+
+// CHECK: [[EHCLEANUP_BB]]:
+// CHECK-NEXT: %[[CLEANUPPAD:.*]] = cleanuppad within %[[CATCHPAD]] []
+// CHECK-NEXT: call void @__cxa_end_catch() {{.*}} [ "funclet"(token %[[CLEANUPPAD]]) ]
+// CHECK-NEXT: cleanupret from %[[CLEANUPPAD]] unwind to caller
+
+// Possibly throwing function call within a catch-all
+void test5() {
+ try {
+ may_throw();
+ } catch (...) {
+ may_throw();
+ }
+}
+
+// CHECK-LABEL: @_Z5test5v()
+
+// CHECK: %[[CATCHSWITCH:.*]] = catchswitch within none [label %[[CATCHSTART_BB]]] unwind to caller
+
+// CHECK: [[CATCHSTART_BB]]:
+// CHECK: %[[CATCHPAD:.*]] = catchpad within %[[CATCHSWITCH]] [i8* null]
+
+// CHECK: invoke void @_Z9may_throwv() [ "funclet"(token %[[CATCHPAD]]) ]
+// CHECK-NEXT: to label %[[INVOKE_CONT_BB0:.*]] unwind label %[[EHCLEANUP_BB:.*]]
+
+// CHECK: [[INVOKE_CONT_BB0]]:
+// CHECK-NEXT: call void @__cxa_end_catch() [ "funclet"(token %[[CATCHPAD]]) ]
+// CHECK-NEXT: catchret from %[[CATCHPAD]] to label
+
+// CHECK: [[EHCLEANUP_BB]]:
+// CHECK-NEXT: %[[CLEANUPPAD0:.*]] = cleanuppad within %[[CATCHPAD]] []
+// CHECK-NEXT: invoke void @__cxa_end_catch() [ "funclet"(token %[[CLEANUPPAD0]]) ]
+// CHECK-NEXT: to label %[[INVOKE_CONT_BB1:.*]] unwind label %[[TERMINATE_BB:.*]]
+
+// CHECK: [[INVOKE_CONT_BB1]]:
+// CHECK-NEXT: cleanupret from %[[CLEANUPPAD0]] unwind to caller
+
+// CHECK: [[TERMINATE_BB]]:
+// CHECK-NEXT: %[[CLEANUPPAD1:.*]] = cleanuppad within %[[CLEANUPPAD0]] []
+// CHECK-NEXT: %[[EXN:.*]] = call i8* @llvm.wasm.get.exception(token %[[CLEANUPPAD1]])
+// CHECK-NEXT: call void @__clang_call_terminate(i8* %[[EXN]]) {{.*}} [ "funclet"(token %[[CLEANUPPAD1]]) ]
+// CHECK-NEXT: unreachable
+
+// CHECK-LABEL: define {{.*}} void @__clang_call_terminate(i8*)
+// CHECK-NEXT: call i8* @__cxa_begin_catch(i8* %{{.*}})
+// CHECK-NEXT: call void @_ZSt9terminatev()
+// CHECK-NEXT: unreachable
+
+// Try-catch with cleanups
+void test6() {
+ Cleanup c1;
+ try {
+ Cleanup c2;
+ may_throw();
+ } catch (int) {
+ Cleanup c3;
+ may_throw();
+ }
+}
+
+// CHECK-LABEL: @_Z5test6v()
+// CHECK: invoke void @_Z9may_throwv()
+// CHECK-NEXT: to label %{{.*}} unwind label %[[EHCLEANUP_BB0:.*]]
+
+// CHECK: [[EHCLEANUP_BB0]]:
+// CHECK-NEXT: %[[CLEANUPPAD0:.*]] = cleanuppad within none []
+// CHECK-NEXT: call %struct.Cleanup* @_ZN7CleanupD1Ev(%struct.Cleanup* {{.*}}) {{.*}} [ "funclet"(token %[[CLEANUPPAD0]]) ]
+// CHECK-NEXT: cleanupret from %[[CLEANUPPAD0]] unwind label %[[CATCH_DISPATCH_BB:.*]]
+
+// CHECK: [[CATCH_DISPATCH_BB]]:
+// CHECK-NEXT: %[[CATCHSWITCH:.*]] = catchswitch within none [label %[[CATCHSTART_BB:.*]]] unwind label %[[EHCLEANUP_BB1:.*]]
+
+// CHECK: [[CATCHSTART_BB]]:
+// CHECK-NEXT: %[[CATCHPAD:.*]] = catchpad within %[[CATCHSWITCH]] [i8* bitcast (i8** @_ZTIi to i8*)]
+// CHECK: br i1 %{{.*}}, label %[[CATCH_INT_BB:.*]], label %[[RETHROW_BB:.*]]
+
+// CHECK: [[CATCH_INT_BB]]:
+// CHECK: invoke void @_Z9may_throwv() [ "funclet"(token %[[CATCHPAD]]) ]
+// CHECK-NEXT: to label %[[INVOKE_CONT_BB:.*]] unwind label %[[EHCLEANUP_BB2:.*]]
+
+// CHECK: [[INVOKE_CONT_BB]]:
+// CHECK: catchret from %[[CATCHPAD]] to label %{{.*}}
+
+// CHECK: [[RETHROW_BB]]:
+// CHECK-NEXT: invoke void @__cxa_rethrow() {{.*}} [ "funclet"(token %[[CATCHPAD]]) ]
+// CHECK-NEXT: to label %[[UNREACHABLE_BB:.*]] unwind label %[[EHCLEANUP_BB1:.*]]
+
+// CHECK: [[EHCLEANUP_BB2]]:
+// CHECK-NEXT: %[[CLEANUPPAD2:.*]] = cleanuppad within %[[CATCHPAD]] []
+// CHECK-NEXT: call %struct.Cleanup* @_ZN7CleanupD1Ev(%struct.Cleanup* %{{.*}}) {{.*}} [ "funclet"(token %[[CLEANUPPAD2]]) ]
+// CHECK-NEXT: cleanupret from %[[CLEANUPPAD2]] unwind label %[[EHCLEANUP_BB3:.*]]
+
+// CHECK: [[EHCLEANUP_BB3]]:
+// CHECK-NEXT: %[[CLEANUPPAD3:.*]] = cleanuppad within %[[CATCHPAD]] []
+// CHECK: cleanupret from %[[CLEANUPPAD3]] unwind label %[[EHCLEANUP_BB1:.*]]
+
+// CHECK: [[EHCLEANUP_BB1]]:
+// CHECK-NEXT: %[[CLEANUPPAD1:.*]] = cleanuppad within none []
+// CHECK-NEXT: call %struct.Cleanup* @_ZN7CleanupD1Ev(%struct.Cleanup* %{{.*}}) {{.*}} [ "funclet"(token %[[CLEANUPPAD1]]) ]
+// CHECK-NEXT: cleanupret from %[[CLEANUPPAD1]] unwind to caller
+
+// CHECK: [[UNREACHABLE_BB]]:
+// CHECK-NEXT: unreachable
+
+// Nested try-catches within a try with cleanups
+void test7() {
+ Cleanup c1;
+ may_throw();
+ try {
+ Cleanup c2;
+ may_throw();
+ try {
+ Cleanup c3;
+ may_throw();
+ } catch (int) {
+ may_throw();
+ } catch (double) {
+ may_throw();
+ }
+ } catch (int) {
+ may_throw();
+ } catch (...) {
+ may_throw();
+ }
+}
+
+// CHECK-LABEL: @_Z5test7v()
+// CHECK: invoke void @_Z9may_throwv()
+
+// CHECK: invoke void @_Z9may_throwv()
+
+// CHECK: invoke void @_Z9may_throwv()
+
+// CHECK: %[[CLEANUPPAD0:.*]] = cleanuppad within none []
+// CHECK: cleanupret from %[[CLEANUPPAD0]] unwind label
+
+// CHECK: %[[CATCHSWITCH0:.*]] = catchswitch within none
+
+// CHECK: %[[CATCHPAD0:.*]] = catchpad within %[[CATCHSWITCH0]] [i8* bitcast (i8** @_ZTIi to i8*), i8* bitcast (i8** @_ZTId to i8*)]
+
+// CHECK: invoke void @_Z9may_throwv() [ "funclet"(token %[[CATCHPAD0]]) ]
+
+// CHECK: catchret from %[[CATCHPAD0]] to label
+
+// CHECK: invoke void @_Z9may_throwv() [ "funclet"(token %[[CATCHPAD0]]) ]
+
+// CHECK: catchret from %[[CATCHPAD0]] to label
+
+// CHECK: invoke void @__cxa_rethrow() {{.*}} [ "funclet"(token %[[CATCHPAD0]]) ]
+
+// CHECK: %[[CLEANUPPAD1:.*]] = cleanuppad within %[[CATCHPAD0]] []
+// CHECK: cleanupret from %[[CLEANUPPAD1]] unwind label
+
+// CHECK: %[[CLEANUPPAD2:.*]] = cleanuppad within %[[CATCHPAD0]] []
+// CHECK: cleanupret from %[[CLEANUPPAD2]] unwind label
+
+// CHECK: %[[CLEANUPPAD3:.*]] = cleanuppad within none []
+// CHECK: cleanupret from %[[CLEANUPPAD3]] unwind label
+
+// CHECK: %[[CATCHSWITCH1:.*]] = catchswitch within none
+
+// CHECK: %[[CATCHPAD1:.*]] = catchpad within %[[CATCHSWITCH1]] [i8* bitcast (i8** @_ZTIi to i8*), i8* null]
+
+// CHECK: invoke void @_Z9may_throwv() [ "funclet"(token %[[CATCHPAD1]]) ]
+
+// CHECK: catchret from %[[CATCHPAD1]] to label
+
+// CHECK: invoke void @_Z9may_throwv() [ "funclet"(token %[[CATCHPAD1]]) ]
+
+// CHECK: invoke void @__cxa_end_catch() [ "funclet"(token %[[CATCHPAD1]]) ]
+
+// CHECK: catchret from %[[CATCHPAD1]] to label
+
+// CHECK: %[[CLEANUPPAD4:.*]] = cleanuppad within %[[CATCHPAD1]] []
+// CHECK: invoke void @__cxa_end_catch() [ "funclet"(token %[[CLEANUPPAD4]]) ]
+
+// CHECK: cleanupret from %[[CLEANUPPAD4]] unwind label
+
+// CHECK: %[[CLEANUPPAD5:.*]] = cleanuppad within %[[CATCHPAD1]] []
+// CHECK: cleanupret from %[[CLEANUPPAD5]] unwind label
+
+// CHECK: %[[CLEANUPPAD6:.*]] = cleanuppad within none []
+// CHECK: cleanupret from %[[CLEANUPPAD6]] unwind to caller
+
+// CHECK: unreachable
+
+// CHECK: %[[CLEANUPPAD7:.*]] = cleanuppad within %[[CLEANUPPAD4]] []
+// CHECK: call void @__clang_call_terminate(i8* %{{.*}}) {{.*}} [ "funclet"(token %[[CLEANUPPAD7]]) ]
+// CHECK: unreachable
+
+// Nested try-catches within a catch
+void test8() {
+ try {
+ may_throw();
+ } catch (int) {
+ try {
+ may_throw();
+ } catch (int) {
+ may_throw();
+ }
+ }
+}
+
+// CHECK-LABEL: @_Z5test8v()
+// CHECK: invoke void @_Z9may_throwv()
+
+// CHECK: %[[CATCHSWITCH0:.*]] = catchswitch within none
+
+// CHECK: %[[CATCHPAD0:.*]] = catchpad within %[[CATCHSWITCH0]] [i8* bitcast (i8** @_ZTIi to i8*)]
+
+// CHECK: invoke void @_Z9may_throwv() [ "funclet"(token %[[CATCHPAD0]]) ]
+
+// CHECK: %[[CATCHSWITCH1:.*]] = catchswitch within %[[CATCHPAD0]]
+
+// CHECK: %[[CATCHPAD1:.*]] = catchpad within %[[CATCHSWITCH1]] [i8* bitcast (i8** @_ZTIi to i8*)]
+
+// CHECK: invoke void @_Z9may_throwv() [ "funclet"(token %[[CATCHPAD1]]) ]
+
+// CHECK: catchret from %[[CATCHPAD1]] to label
+
+// CHECK: invoke void @__cxa_rethrow() {{.*}} [ "funclet"(token %[[CATCHPAD1]]) ]
+
+// CHECK: catchret from %[[CATCHPAD0]] to label
+
+// CHECK: call void @__cxa_rethrow() {{.*}} [ "funclet"(token %[[CATCHPAD0]]) ]
+// CHECK: unreachable
+
+// CHECK: %[[CLEANUPPAD0:.*]] = cleanuppad within %[[CATCHPAD1]] []
+// CHECK: cleanupret from %[[CLEANUPPAD0]] unwind label
+
+// CHECK: %[[CLEANUPPAD1:.*]] = cleanuppad within %[[CATCHPAD0]] []
+// CHECK: cleanupret from %[[CLEANUPPAD1]] unwind to caller
+
+// CHECK: unreachable
diff --git a/src/llvm-project/clang/test/CodeGenCXX/weak-extern-typeinfo.cpp b/src/llvm-project/clang/test/CodeGenCXX/weak-extern-typeinfo.cpp
new file mode 100644
index 0000000..6bbb473
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/weak-extern-typeinfo.cpp
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 %s -emit-llvm -triple %itanium_abi_triple -o - | FileCheck %s
+// rdar://10246395
+
+#define WEAK __attribute__ ((weak))
+
+class WEAK A {
+ virtual void foo();
+};
+
+class B : public A {
+ virtual void foo();
+};
+void A::foo() { }
+void B::foo() { }
+
+class T {};
+class T1 {};
+
+class C : public T1, public B, public T {
+ virtual void foo();
+};
+void C::foo() { }
+
+class V1 : public virtual A {
+ virtual void foo();
+};
+
+class V2 : public virtual V1 {
+ virtual void foo();
+};
+void V1::foo() { }
+void V2::foo() { }
+
+// CHECK: @_ZTS1A = weak_odr {{(dso_local )?}}constant
+// CHECK: @_ZTI1A = weak_odr {{(dso_local )?}}constant
+// CHECK: @_ZTS1B = weak_odr {{(dso_local )?}}constant
+// CHECK: @_ZTI1B = weak_odr {{(dso_local )?}}constant
+// CHECK: @_ZTS1C = weak_odr {{(dso_local )?}}constant
+// CHECK: @_ZTS2T1 = linkonce_odr {{(dso_local )?}}constant
+// CHECK: @_ZTI2T1 = linkonce_odr {{(dso_local )?}}constant
+// CHECK: @_ZTS1T = linkonce_odr {{(dso_local )?}}constant
+// CHECK: @_ZTI1T = linkonce_odr {{(dso_local )?}}constant
+// CHECK: @_ZTI1C = weak_odr {{(dso_local )?}}constant
+// CHECK: @_ZTS2V1 = weak_odr {{(dso_local )?}}constant
+// CHECK: @_ZTI2V1 = weak_odr {{(dso_local )?}}constant
+// CHECK: @_ZTS2V2 = weak_odr {{(dso_local )?}}constant
+// CHECK: @_ZTI2V2 = weak_odr {{(dso_local )?}}constant
diff --git a/src/llvm-project/clang/test/CodeGenCXX/weak-external.cpp b/src/llvm-project/clang/test/CodeGenCXX/weak-external.cpp
new file mode 100644
index 0000000..a2c53a5
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/weak-external.cpp
@@ -0,0 +1,66 @@
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -triple %itanium_abi_triple %s -S -emit-llvm -o - | FileCheck %s
+// PR4262
+
+// CHECK-NOT: _ZNSs12_S_constructIPKcEEPcT_S3_RKSaIcESt20forward_iterator_tag
+
+// The "basic_string" extern template instantiation declaration is supposed to
+// suppress the implicit instantiation of non-inline member functions. Make sure
+// that we suppress the implicit instantiation of non-inline member functions
+// defined out-of-line. That we aren't instantiating the basic_string
+// constructor when we shouldn't be. Such an instantiation forces the implicit
+// instantiation of _S_construct<const char*>. Since _S_construct is a member
+// template, it's instantiation is *not* suppressed (despite being in
+// basic_string<char>), so we would emit it as a weak definition.
+
+#define _LIBCPP_EXCEPTION_ABI __attribute__ ((__visibility__("default")))
+#define _LIBCPP_INLINE_VISIBILITY __attribute__ ((__visibility__("hidden"), __always_inline__))
+#define _LIBCPP_VISIBLE __attribute__ ((__visibility__("default")))
+#if (__has_feature(cxx_noexcept))
+# define _NOEXCEPT noexcept
+# define _NOEXCEPT_(x) noexcept(x)
+#else
+# define _NOEXCEPT throw()
+# define _NOEXCEPT_(x)
+#endif
+
+namespace std // purposefully not using versioning namespace
+{
+
+template<class charT> struct char_traits;
+template<class T> class allocator;
+template <class _CharT,
+ class _Traits = char_traits<_CharT>,
+ class _Allocator = allocator<_CharT> >
+ class _LIBCPP_VISIBLE basic_string;
+typedef basic_string<char, char_traits<char>, allocator<char> > string;
+
+class _LIBCPP_EXCEPTION_ABI exception
+{
+public:
+ _LIBCPP_INLINE_VISIBILITY exception() _NOEXCEPT {}
+ virtual ~exception() _NOEXCEPT;
+ virtual const char* what() const _NOEXCEPT;
+};
+
+class _LIBCPP_EXCEPTION_ABI runtime_error
+ : public exception
+{
+private:
+ void* __imp_;
+public:
+ explicit runtime_error(const string&);
+ explicit runtime_error(const char*);
+
+ runtime_error(const runtime_error&) _NOEXCEPT;
+ runtime_error& operator=(const runtime_error&) _NOEXCEPT;
+
+ virtual ~runtime_error() _NOEXCEPT;
+
+ virtual const char* what() const _NOEXCEPT;
+};
+
+}
+
+void dummysymbol() {
+ throw(std::runtime_error("string"));
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/windows-implicit-dllexport-template-specialization.cpp b/src/llvm-project/clang/test/CodeGenCXX/windows-implicit-dllexport-template-specialization.cpp
new file mode 100644
index 0000000..20ba4bc
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/windows-implicit-dllexport-template-specialization.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -std=c++11 -triple i686-windows -fdeclspec -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-MS
+// RUN: %clang_cc1 -std=c++11 -triple i686-windows-itanium -fdeclspec -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-IA
+
+template <typename>
+struct s {};
+
+template <typename T_>
+class t : s<T_> {};
+
+extern template class t<char>;
+template class __declspec(dllexport) t<char>;
+
+// CHECK-MS: dllexport {{.*}} @"??4?$t@D@@QAEAAV0@ABV0@@Z"
+// CHECK-MS: dllexport {{.*}} @"??4?$s@D@@QAEAAU0@ABU0@@Z"
+
+// CHECK-IA: dllexport {{.*}} @_ZN1tIcEaSERKS0_
+// CHECK-IA: dllexport {{.*}} @_ZN1sIcEaSERKS0_
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/windows-itanium-dllexport.cpp b/src/llvm-project/clang/test/CodeGenCXX/windows-itanium-dllexport.cpp
new file mode 100644
index 0000000..ff780c7
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/windows-itanium-dllexport.cpp
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -emit-llvm -triple i686-windows-itanium -fdeclspec %s -o - | FileCheck %s
+
+#define JOIN2(x, y) x##y
+#define JOIN(x, y) JOIN2(x, y)
+#define UNIQ(name) JOIN(name, __LINE__)
+#define USEMEMFUNC(class, func) void (class::*UNIQ(use)())() { return &class::func; }
+
+struct __declspec(dllexport) s {
+ void f() {}
+};
+
+// CHECK: define {{.*}} dllexport {{.*}} @_ZN1saSERKS_
+// CHECK: define {{.*}} dllexport {{.*}} @_ZN1s1fEv
+
+template <class T>
+class c {
+ void f() {}
+};
+
+template class __declspec(dllexport) c<int>;
+
+// CHECK: define {{.*}} dllexport {{.*}} @_ZN1cIiEaSERKS0_
+// CHECK: define {{.*}} dllexport {{.*}} @_ZN1cIiE1fEv
+
+extern template class c<char>;
+template class __declspec(dllexport) c<char>;
+
+// CHECK: define {{.*}} dllexport {{.*}} @_ZN1cIcEaSERKS0_
+// CHECK: define {{.*}} dllexport {{.*}} @_ZN1cIcE1fEv
+
+c<double> g;
+template class __declspec(dllexport) c<double>;
+
+// CHECK: define {{.*}} dllexport {{.*}} @_ZN1cIdEaSERKS0_
+// CHECK: define {{.*}} dllexport {{.*}} @_ZN1cIdE1fEv
+
+template <class T>
+struct outer {
+ void f() {}
+ struct inner {
+ void f() {}
+ };
+};
+
+template class __declspec(dllexport) outer<int>;
+
+// CHECK: define {{.*}} dllexport {{.*}} @_ZN5outerIiE1fEv
+// CHECK-NOT: define {{.*}} dllexport {{.*}} @_ZN5outerIiE5inner1fEv
+
+extern template class __declspec(dllimport) outer<char>;
+USEMEMFUNC(outer<char>, f)
+USEMEMFUNC(outer<char>::inner, f)
+
+// CHECK: declare dllimport {{.*}} @_ZN5outerIcE1fEv
+// CHECK: define {{.*}} @_ZN5outerIcE5inner1fEv
diff --git a/src/llvm-project/clang/test/CodeGenCXX/windows-itanium-exceptions.cpp b/src/llvm-project/clang/test/CodeGenCXX/windows-itanium-exceptions.cpp
new file mode 100644
index 0000000..1bca4e8
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/windows-itanium-exceptions.cpp
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -emit-llvm -triple thumbv7-windows-itanium -fexceptions -fcxx-exceptions %s -o - | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -triple i686-windows-itanium -fexceptions -fcxx-exceptions %s -o - | FileCheck %s
+// REQUIRES: asserts
+
+void except() {
+ throw 32;
+}
+
+void attempt() {
+ try { except(); } catch (...) { }
+}
+
+// CHECK: @_ZTIi = external dso_local constant i8*
+
+// CHECK: define {{.*}}void @_Z6exceptv() {{.*}} {
+// CHECK: %exception = call {{.*}}i8* @__cxa_allocate_exception(i32 4)
+// CHECK: %0 = bitcast i8* %exception to i32*
+// CHECK: store i32 32, i32* %0
+// CHECK: call {{.*}}void @__cxa_throw(i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null)
+// CHECK: unreachable
+// CHECK: }
+
+// CHECK: define {{.*}}void @_Z7attemptv()
+// CHECK-SAME: personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+// CHECK: %exn.slot = alloca i8*
+// CHECK: %ehselector.slot = alloca i32
+// CHECK: invoke {{.*}}void @_Z6exceptv()
+// CHECK: to label %invoke.cont unwind label %lpad
+// CHECK: invoke.cont:
+// CHECK: br label %try.cont
+// CHECK: lpad:
+// CHECK: %0 = landingpad { i8*, i32 }
+// CHECK: catch i8* null
+// CHECK: %1 = extractvalue { i8*, i32 } %0, 0
+// CHECK: store i8* %1, i8** %exn.slot
+// CHECK: %2 = extractvalue { i8*, i32 } %0, 1
+// CHECK: store i32 %2, i32* %ehselector.slot
+// CHECK: br label %catch
+// CHECK: catch:
+// CHECK: %exn = load i8*, i8** %exn.slot
+// CHECK: %3 = call {{.*}}i8* @__cxa_begin_catch(i8* %{{2|exn}})
+// CHECK: call {{.*}}void @__cxa_end_catch()
+// CHECK: br label %try.cont
+// CHECK: try.cont:
+// CHECK: ret void
+// CHECK: }
+
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/windows-itanium-type-info.cpp b/src/llvm-project/clang/test/CodeGenCXX/windows-itanium-type-info.cpp
new file mode 100644
index 0000000..20bd78d
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/windows-itanium-type-info.cpp
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -triple i686-windows-itanium -fdeclspec -fcxx-exceptions -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple i686-windows-itanium -fdeclspec -fcxx-exceptions -fno-rtti -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-EH-IMPORT
+
+namespace __cxxabiv1 {
+class __declspec(dllexport) __fundamental_type_info {
+public:
+ virtual ~__fundamental_type_info();
+};
+
+__fundamental_type_info::~__fundamental_type_info() {}
+}
+
+struct __declspec(dllimport) base {
+ virtual void method();
+};
+struct __declspec(dllexport) derived : base {
+ virtual ~derived();
+};
+derived::~derived() {
+ method();
+}
+
+void f() {
+ throw base();
+}
+
+// CHECK-DAG: @_ZTIi = dso_local dllexport constant
+// CHECK-DAG: @_ZTSi = dso_local dllexport constant
+
+// CHECK-DAG: @_ZTI7derived = dso_local dllexport constant
+// CHECK-DAG: @_ZTS7derived = dso_local dllexport constant
+// CHECK-DAG: @_ZTV7derived = dso_local dllexport unnamed_addr constant
+
+// CHECK-DAG: @_ZTI4base = external dllimport constant
+
+// CHECK-EH-IMPORT: @_ZTS4base = linkonce_odr dso_local constant
+// CHECK-EH-IMPORT: @_ZTI4base = linkonce_odr dso_local constant
+
+struct __declspec(dllimport) gatekeeper {};
+struct zuul : gatekeeper {
+ virtual ~zuul();
+};
+zuul::~zuul() {}
+
+// CHECK-DAG: @_ZTI10gatekeeper = linkonce_odr dso_local constant
+// CHECK-DAG: @_ZTS10gatekeeper = linkonce_odr dso_local constant
diff --git a/src/llvm-project/clang/test/CodeGenCXX/windows-on-arm-stack-probe-size.cpp b/src/llvm-project/clang/test/CodeGenCXX/windows-on-arm-stack-probe-size.cpp
new file mode 100644
index 0000000..235d8a0
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/windows-on-arm-stack-probe-size.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -triple thumbv7--windows-msvc -S -emit-llvm -o - -x c++ %s | FileCheck %s
+// RUN: %clang_cc1 -triple thumbv7--windows-itanium -fno-use-cxa-atexit -S -emit-llvm -o - -x c++ %s | FileCheck %s
+
+class C {
+public:
+ ~C();
+};
+
+static C sc;
+void f(const C &ci) { sc = ci; }
+
+// CHECK: atexit
+
diff --git a/src/llvm-project/clang/test/CodeGenCXX/x86_32-arguments.cpp b/src/llvm-project/clang/test/CodeGenCXX/x86_32-arguments.cpp
new file mode 100644
index 0000000..2c7234e
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/x86_32-arguments.cpp
@@ -0,0 +1,116 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -emit-llvm -o - %s | FileCheck %s
+
+// Non-trivial dtors, should both be passed indirectly.
+struct S {
+ ~S();
+ short s;
+};
+
+// CHECK-LABEL: define void @_Z1fv(%struct.S* noalias sret %
+S f() { return S(); }
+// CHECK-LABEL: define void @_Z1f1S(%struct.S*)
+void f(S) { }
+
+// Non-trivial dtors, should both be passed indirectly.
+class C {
+public:
+ ~C();
+ double c;
+};
+
+// CHECK-LABEL: define void @_Z1gv(%class.C* noalias sret %
+C g() { return C(); }
+
+// CHECK-LABEL: define void @_Z1f1C(%class.C*)
+void f(C) { }
+
+
+
+
+// PR7058 - Missing byval on MI thunk definition.
+
+// CHECK-LABEL: define void @_ZThn4_N18BasicAliasAnalysis13getModRefInfoE8CallSite
+// ...
+// CHECK: %struct.CallSite* byval align 4 %CS)
+struct CallSite {
+ unsigned Ptr;
+ CallSite(unsigned XX) : Ptr(XX) {}
+};
+
+struct AliasAnalysis {
+ virtual void xyz();
+ virtual void getModRefInfo(CallSite CS) = 0;
+};
+
+struct ModulePass {
+ virtual void xx();
+};
+
+struct BasicAliasAnalysis : public ModulePass, public AliasAnalysis {
+ void getModRefInfo(CallSite CS);
+};
+
+void BasicAliasAnalysis::getModRefInfo(CallSite CS) {
+}
+
+// Check various single element struct type conditions.
+//
+// PR7098.
+
+// CHECK-LABEL: define i64 @_Z2f0v()
+struct s0_0 { int x; };
+struct s0_1 : s0_0 { int* y; };
+s0_1 f0() { return s0_1(); }
+
+// CHECK-LABEL: define i32 @_Z2f1v()
+struct s1_0 { int x; };
+struct s1_1 : s1_0 { };
+s1_1 f1() { return s1_1(); }
+
+// CHECK-LABEL: define double @_Z2f2v()
+struct s2_0 { double x; };
+struct s2_1 : s2_0 { };
+s2_1 f2() { return s2_1(); }
+
+// CHECK-LABEL: define double @_Z2f3v()
+struct s3_0 { };
+struct s3_1 { double x; };
+struct s3_2 : s3_0, s3_1 { };
+s3_2 f3() { return s3_2(); }
+
+// CHECK-LABEL: define i64 @_Z2f4v()
+struct s4_0 { float x; };
+struct s4_1 { float x; };
+struct s4_2 : s4_0, s4_1 { };
+s4_2 f4() { return s4_2(); }
+
+// CHECK-LABEL: define i32* @_Z2f5v()
+struct s5 { s5(); int &x; };
+s5 f5() { return s5(); }
+
+// CHECK-LABEL: define i32 @_Z4f6_0M2s6i(i32 %a)
+// CHECK: define i64 @_Z4f6_1M2s6FivE({ i32, i32 }* byval align 4)
+// FIXME: It would be nice to avoid byval on the previous case.
+struct s6 {};
+typedef int s6::* s6_mdp;
+typedef int (s6::*s6_mfp)();
+s6_mdp f6_0(s6_mdp a) { return a; }
+s6_mfp f6_1(s6_mfp a) { return a; }
+
+// CHECK-LABEL: define double @_Z2f7v()
+struct s7_0 { unsigned : 0; };
+struct s7_1 { double x; };
+struct s7 : s7_0, s7_1 { };
+s7 f7() { return s7(); }
+
+// CHECK-LABEL: define void @_Z2f8v(%struct.s8* noalias sret %agg.result)
+struct s8_0 { };
+struct s8_1 { double x; };
+struct s8 { s8_0 a; s8_1 b; };
+s8 f8() { return s8(); }
+
+// CHECK-LABEL: define void @_Z2f9v(%struct.s9* noalias sret %agg.result)
+struct s9_0 { unsigned : 0; };
+struct s9_1 { double x; };
+struct s9 { s9_0 a; s9_1 b; };
+s9 f9() { return s9(); }
diff --git a/src/llvm-project/clang/test/CodeGenCXX/x86_64-arguments-avx.cpp b/src/llvm-project/clang/test/CodeGenCXX/x86_64-arguments-avx.cpp
new file mode 100644
index 0000000..2933d94
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/x86_64-arguments-avx.cpp
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s -target-feature +avx | FileCheck %s
+
+namespace test1 {
+typedef double __m256d __attribute__((__vector_size__(32)));
+
+class PR22753 {
+public:
+ __m256d data;
+};
+
+// CHECK: define <4 x double> @_ZN5test14testENS_7PR22753E(<4 x double>
+PR22753 test(PR22753 x) {
+ return x;
+}
+}
+
+namespace test2 {
+typedef double __m128d __attribute__((__vector_size__(16)));
+typedef float __m128 __attribute__((__vector_size__(16)));
+typedef double __m256d __attribute__((__vector_size__(32)));
+typedef float __m256 __attribute__((__vector_size__(32)));
+
+union U1 {
+ __m128 v1;
+ __m128d v2;
+};
+
+union UU1 {
+ union U1;
+ __m128d v3;
+};
+
+// CHECK: define <2 x double> @_ZN5test27PR23082ENS_3UU1E(<2 x double>
+UU1 PR23082(UU1 x) {
+ return x;
+}
+
+union U2 {
+ __m256 v1;
+ __m256d v2;
+};
+
+union UU2 {
+ union U2;
+ __m256d v3;
+};
+
+// CHECK: define <4 x double> @_ZN5test27PR23082ENS_3UU2E(<4 x double>
+UU2 PR23082(UU2 x) {
+ return x;
+}
+}
+
+namespace test3 {
+union U {
+ __attribute__((__vector_size__(32))) float f1;
+ int f2;
+};
+// CHECK: define i32 @_ZN5test31fENS_1UE({{.*}}* byval align 32
+int f(U u) { return u.f2; }
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/x86_64-arguments-nacl-x32.cpp b/src/llvm-project/clang/test/CodeGenCXX/x86_64-arguments-nacl-x32.cpp
new file mode 100644
index 0000000..3392b32
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/x86_64-arguments-nacl-x32.cpp
@@ -0,0 +1,57 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-nacl -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -triple=x86_64-unknown-linux-gnux32 -emit-llvm -o - %s | FileCheck %s
+
+struct test_struct {};
+typedef int test_struct::* test_struct_mdp;
+typedef int (test_struct::*test_struct_mfp)();
+
+// CHECK-LABEL: define i32 @{{.*}}f_mdp{{.*}}(i32 %a)
+test_struct_mdp f_mdp(test_struct_mdp a) { return a; }
+
+// CHECK-LABEL: define {{.*}} @{{.*}}f_mfp{{.*}}(i64 %a.coerce)
+test_struct_mfp f_mfp(test_struct_mfp a) { return a; }
+
+// A struct with <= 12 bytes before a member data pointer should still
+// be allowed in registers, since the member data pointer is only 4 bytes.
+// CHECK-LABEL: define void @{{.*}}f_struct_with_mdp{{.*}}(i64 %a.coerce0, i64 %a.coerce1)
+struct struct_with_mdp { char *a; char *b; char *c; test_struct_mdp d; };
+void f_struct_with_mdp(struct_with_mdp a) { (void)a; }
+
+struct struct_with_mdp_too_much {
+ char *a; char *b; char *c; char *d; test_struct_mdp e;
+};
+// CHECK-LABEL: define void @{{.*}}f_struct_with_mdp_too_much{{.*}}({{.*}} byval {{.*}} %a)
+void f_struct_with_mdp_too_much(struct_with_mdp_too_much a) {
+ (void)a;
+}
+
+// A struct with <= 8 bytes before a member function pointer should still
+// be allowed in registers, since the member function pointer is only 8 bytes.
+// CHECK-LABEL: define void @{{.*}}f_struct_with_mfp_0{{.*}}(i64 %a.coerce0, i32 %a.coerce1)
+struct struct_with_mfp_0 { char *a; test_struct_mfp b; };
+void f_struct_with_mfp_0(struct_with_mfp_0 a) { (void)a; }
+
+// CHECK-LABEL: define void @{{.*}}f_struct_with_mfp_1{{.*}}(i64 %a.coerce0, i64 %a.coerce1)
+struct struct_with_mfp_1 { char *a; char *b; test_struct_mfp c; };
+void f_struct_with_mfp_1(struct_with_mfp_1 a) { (void)a; }
+
+// CHECK-LABEL: define void @{{.*}}f_struct_with_mfp_too_much{{.*}}({{.*}} byval {{.*}} %a, i32 %x)
+struct struct_with_mfp_too_much {
+ char *a; char *b; char *c; test_struct_mfp d;
+};
+void f_struct_with_mfp_too_much(struct_with_mfp_too_much a, int x) {
+ (void)a;
+}
+
+/* Struct containing an empty struct */
+typedef struct { int* a; test_struct x; double *b; } struct_with_empty;
+
+// CHECK-LABEL: define void @{{.*}}f_pass_struct_with_empty{{.*}}(i64 %x{{.*}}, double* %x
+void f_pass_struct_with_empty(struct_with_empty x) {
+ (void) x;
+}
+
+// CHECK-LABEL: define { i64, double* } @{{.*}}f_return_struct_with_empty
+struct_with_empty f_return_struct_with_empty() {
+ return {0, {}, 0};
+}
diff --git a/src/llvm-project/clang/test/CodeGenCXX/x86_64-arguments.cpp b/src/llvm-project/clang/test/CodeGenCXX/x86_64-arguments.cpp
new file mode 100644
index 0000000..c7eca23
--- /dev/null
+++ b/src/llvm-project/clang/test/CodeGenCXX/x86_64-arguments.cpp
@@ -0,0 +1,223 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s
+
+// Basic base class test.
+struct f0_s0 { unsigned a; };
+struct f0_s1 : public f0_s0 { void *b; };
+// CHECK-LABEL: define void @_Z2f05f0_s1(i32 %a0.coerce0, i8* %a0.coerce1)
+void f0(f0_s1 a0) { }
+
+// Check with two eight-bytes in base class.
+struct f1_s0 { unsigned a; unsigned b; float c; };
+struct f1_s1 : public f1_s0 { float d;};
+// CHECK-LABEL: define void @_Z2f15f1_s1(i64 %a0.coerce0, <2 x float> %a0.coerce1)
+void f1(f1_s1 a0) { }
+
+// Check with two eight-bytes in base class and merge.
+struct f2_s0 { unsigned a; unsigned b; float c; };
+struct f2_s1 : public f2_s0 { char d;};
+// CHECK-LABEL: define void @_Z2f25f2_s1(i64 %a0.coerce0, i64 %a0.coerce1)
+void f2(f2_s1 a0) { }
+
+// PR5831
+// CHECK-LABEL: define void @_Z2f34s3_1(i64 %x.coerce)
+struct s3_0 {};
+struct s3_1 { struct s3_0 a; long b; };
+void f3(struct s3_1 x) {}
+
+// CHECK-LABEL: define i64 @_Z4f4_0M2s4i(i64 %a)
+// CHECK: define {{.*}} @_Z4f4_1M2s4FivE(i64 %a.coerce0, i64 %a.coerce1)
+struct s4 {};
+typedef int s4::* s4_mdp;
+typedef int (s4::*s4_mfp)();
+s4_mdp f4_0(s4_mdp a) { return a; }
+s4_mfp f4_1(s4_mfp a) { return a; }
+
+// A struct with <= one eightbyte before a member data pointer should still
+// be allowed in registers.
+// CHECK-LABEL: define void @{{.*}}f_struct_with_mdp{{.*}}(i8* %a.coerce0, i64 %a.coerce1)
+struct struct_with_mdp { char *a; s4_mdp b; };
+void f_struct_with_mdp(struct_with_mdp a) { (void)a; }
+
+// A struct with anything before a member function will be too big and
+// goes in memory.
+// CHECK-LABEL: define void @{{.*}}f_struct_with_mfp_0{{.*}}(%struct{{.*}} byval align 8 %a)
+struct struct_with_mfp_0 { char a; s4_mfp b; };
+void f_struct_with_mfp_0(struct_with_mfp_0 a) { (void)a; }
+
+// CHECK-LABEL: define void @{{.*}}f_struct_with_mfp_1{{.*}}(%struct{{.*}} byval align 8 %a)
+struct struct_with_mfp_1 { void *a; s4_mfp b; };
+void f_struct_with_mfp_1(struct_with_mfp_1 a) { (void)a; }
+
+namespace PR7523 {
+struct StringRef {
+ char *a;
+};
+
+void AddKeyword(StringRef, int x);
+
+void foo() {
+ // CHECK-LABEL: define void @_ZN6PR75233fooEv()
+ // CHECK: call void @_ZN6PR752310AddKeywordENS_9StringRefEi(i8* {{.*}}, i32 4)
+ AddKeyword(StringRef(), 4);
+}
+}
+
+namespace PR7742 { // Also rdar://8250764
+ struct s2 {
+ float a[2];
+ };
+
+ struct c2 : public s2 {};
+
+ // CHECK-LABEL: define <2 x float> @_ZN6PR77423fooEPNS_2c2E(%"struct.PR7742::c2"* %P)
+ c2 foo(c2 *P) {
+ return c2();
+ }
+
+}
+
+namespace PR5179 {
+ struct B {};
+
+ struct B1 : B {
+ int* pa;
+ };
+
+ struct B2 : B {
+ B1 b1;
+ };
+
+ // CHECK-LABEL: define i8* @_ZN6PR51793barENS_2B2E(i32* %b2.coerce)
+ const void *bar(B2 b2) {
+ return b2.b1.pa;
+ }
+}
+
+namespace test5 {
+ struct Xbase { };
+ struct Empty { };
+ struct Y;
+ struct X : public Xbase {
+ Empty empty;
+ Y f();
+ };
+ struct Y : public X {
+ Empty empty;
+ };
+ X getX();
+ int takeY(const Y&, int y);
+ void g() {
+ // rdar://8340348 - The temporary for the X object needs to have a defined
+ // address when passed into X::f as 'this'.
+ takeY(getX().f(), 42);
+ }
+ // CHECK: void @_ZN5test51gEv()
+ // CHECK: alloca %"struct.test5::Y"
+ // CHECK: alloca %"struct.test5::X"
+ // CHECK: alloca %"struct.test5::Y"
+}
+
+
+// rdar://8360877
+namespace test6 {
+ struct outer {
+ int x;
+ struct epsilon_matcher {} e;
+ int f;
+ };
+
+ int test(outer x) {
+ return x.x + x.f;
+ }
+ // CHECK-LABEL: define i32 @_ZN5test64testENS_5outerE(i64 %x.coerce0, i32 %x.coerce1)
+}
+
+namespace test7 {
+ struct StringRef {char* ptr; long len; };
+ class A { public: ~A(); };
+ A x(A, A, long, long, StringRef) { return A(); }
+ // Check that the StringRef is passed byval instead of expanded
+ // (which would split it between registers and memory).
+ // rdar://problem/9686430
+ // CHECK: define void @_ZN5test71xENS_1AES0_llNS_9StringRefE({{.*}} byval align 8)
+
+ // And a couple extra related tests:
+ A y(A, long double, long, long, StringRef) { return A(); }
+ // CHECK: define void @_ZN5test71yENS_1AEellNS_9StringRefE({{.*}} i8*
+ struct StringDouble {char * ptr; double d;};
+ A z(A, A, A, A, A, StringDouble) { return A(); }
+ A zz(A, A, A, A, StringDouble) { return A(); }
+ // CHECK: define void @_ZN5test71zENS_1AES0_S0_S0_S0_NS_12StringDoubleE({{.*}} byval align 8)
+ // CHECK: define void @_ZN5test72zzENS_1AES0_S0_S0_NS_12StringDoubleE({{.*}} i8*
+}
+
+namespace test8 {
+ // CHECK: declare void @_ZN5test83fooENS_1BE(%"class.test8::B"* byval align 8)
+ class A {
+ char big[17];
+ };
+
+ class B : public A {};
+
+ void foo(B b);
+ void bar() {
+ B b;
+ foo(b);
+ }
+}
+
+// PR4242
+namespace test9 {
+ // Large enough to be passed indirectly.
+ struct S { void *data[3]; };
+
+ struct T { void *data[2]; };
+
+ // CHECK: define void @_ZN5test93fooEPNS_1SEPNS_1TE([[S:%.*]]*, [[T:%.*]]*)
+ void foo(S*, T*) {}
+
+ // CHECK: define void @_ZN5test91aEiiiiNS_1TEPv([[S]]* noalias sret {{%.*}}, i32, i32, i32, i32, [[T]]* byval align 8, i8*)
+ S a(int, int, int, int, T, void*) {
+ return S();
+ }
+
+ // CHECK: define [[S]]* @_ZN5test91bEPNS_1SEiiiiNS_1TEPv([[S]]* {{%.*}}, i32, i32, i32, i32, [[T:%.*]]* byval align 8, i8*)
+ S* b(S* sret, int, int, int, int, T, void*) {
+ return sret;
+ }
+
+ // CHECK: define void @_ZN5test91cEiiiNS_1TEPv([[S]]* noalias sret {{%.*}}, i32, i32, i32, i8* {{%.*}}, i8* {{%.*}}, i8*)
+ S c(int, int, int, T, void*) {
+ return S();
+ }
+
+ // CHECK: define [[S]]* @_ZN5test91dEPNS_1SEiiiNS_1TEPv([[S]]* {{%.*}}, i32, i32, i32, i8* {{%.*}}, i8* {{%.*}}, i8*)
+ S* d(S* sret, int, int, int, T, void*) {
+ return sret;
+ }
+}
+
+namespace test10 {
+#pragma pack(1)
+struct BasePacked {
+ char one;
+ short two;
+};
+#pragma pack()
+struct DerivedPacked : public BasePacked {
+ int three;
+};
+// CHECK-LABEL: define i32 @_ZN6test1020FuncForDerivedPackedENS_13DerivedPackedE({{.*}}* byval align 8
+int FuncForDerivedPacked(DerivedPacked d) {
+ return d.three;
+}
+}
+
+namespace test11 {
+union U {
+ float f1;
+ char __attribute__((__vector_size__(1))) f2;
+};
+int f(union U u) { return u.f2[1]; }
+// CHECK-LABEL: define i32 @_ZN6test111fENS_1UE(i32
+}