Re: [PATCH] D18196: [CodeGen] Emit lifetime.end intrinsic after destructor call in landing pad
This revision was automatically updated to reflect the committed changes. Closed by commit rL265197: [CodeGen] Emit lifetime.end intrinsic after objects are destructed in (authored by ahatanak). Changed prior to commit: http://reviews.llvm.org/D18196?vs=52110=52440#toc Repository: rL LLVM http://reviews.llvm.org/D18196 Files: cfe/trunk/lib/CodeGen/CGCleanup.cpp cfe/trunk/lib/CodeGen/CGDecl.cpp cfe/trunk/lib/CodeGen/EHScopeStack.h cfe/trunk/test/CodeGenCXX/destructors.cpp cfe/trunk/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp Index: cfe/trunk/test/CodeGenCXX/destructors.cpp === --- cfe/trunk/test/CodeGenCXX/destructors.cpp +++ cfe/trunk/test/CodeGenCXX/destructors.cpp @@ -4,6 +4,9 @@ // 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: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o - -fcxx-exceptions -fexceptions -O1 -disable-llvm-optzns -std=c++11 > %t2 +// RUN: FileCheck --check-prefix=CHECK6 --input-file=%t2 %s +// REQUIRES: asserts struct A { int a; @@ -428,3 +431,64 @@ 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(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(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(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(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(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(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 Index: cfe/trunk/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp === --- cfe/trunk/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp +++ cfe/trunk/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp @@ -1,4 +1,5 @@ // 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 %s +// RUN: %clang_cc1 -std=c++11 -emit-llvm -O3 -disable-llvm-optzns %s -o - -triple=i386-pc-win32 -mconstructor-aliases -fexceptions -fcxx-exceptions -fno-rtti | FileCheck -check-prefix WIN32 -check-prefix WIN32-LIFETIME %s struct A { A(); @@ -206,3 +207,36 @@ // WIN32: cleanuppad // WIN32: call x86_thiscallcc void @"\01??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 void @"\01?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(i64 1, i8* %[[bc0]]) +// WIN32-LIFETIME: invoke void @"\01?g@lifetime_marker@@YAXXZ"() +// WIN32-LIFETIME-NEXT: to label %[[cont:[^ ]*]] unwind label %[[lpad0:[^ ]*]] +// +// WIN32-LIFETIME: [[cont]]: +// WIN32-LIFETIME: call x86_thiscallcc void @"\01??1C@lifetime_marker@@QAE@XZ"({{.*}}) +// WIN32-LIFETIME: %[[bc1:.*]] = bitcast %"struct.lifetime_marker::C"* %[[c]] to i8* +// WIN32-LIFETIME:
Re: [PATCH] D18196: [CodeGen] Emit lifetime.end intrinsic after destructor call in landing pad
rjmccall added a comment. LGTM. http://reviews.llvm.org/D18196 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D18196: [CodeGen] Emit lifetime.end intrinsic after destructor call in landing pad
ahatanak updated this revision to Diff 52110. ahatanak added a comment. Add "REQUIRES: asserts" to test case to enable checking basic block names. http://reviews.llvm.org/D18196 Files: lib/CodeGen/CGCleanup.cpp lib/CodeGen/CGDecl.cpp lib/CodeGen/EHScopeStack.h test/CodeGenCXX/destructors.cpp test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp Index: test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp === --- test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp +++ test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp @@ -1,4 +1,5 @@ // 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 %s +// RUN: %clang_cc1 -std=c++11 -emit-llvm -O3 -disable-llvm-optzns %s -o - -triple=i386-pc-win32 -mconstructor-aliases -fexceptions -fcxx-exceptions -fno-rtti | FileCheck -check-prefix WIN32 -check-prefix WIN32-LIFETIME %s struct A { A(); @@ -206,3 +207,36 @@ // WIN32: cleanuppad // WIN32: call x86_thiscallcc void @"\01??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 void @"\01?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(i64 1, i8* %[[bc0]]) +// WIN32-LIFETIME: invoke void @"\01?g@lifetime_marker@@YAXXZ"() +// WIN32-LIFETIME-NEXT: to label %[[cont:[^ ]*]] unwind label %[[lpad0:[^ ]*]] +// +// WIN32-LIFETIME: [[cont]]: +// WIN32-LIFETIME: call x86_thiscallcc void @"\01??1C@lifetime_marker@@QAE@XZ"({{.*}}) +// WIN32-LIFETIME: %[[bc1:.*]] = bitcast %"struct.lifetime_marker::C"* %[[c]] to i8* +// WIN32-LIFETIME: call void @llvm.lifetime.end(i64 1, i8* %[[bc1]]) +// +// WIN32-LIFETIME: [[lpad0]]: +// WIN32-LIFETIME-NEXT: cleanuppad +// WIN32-LIFETIME: call x86_thiscallcc void @"\01??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(i64 1, i8* %[[bc2]]) +} Index: test/CodeGenCXX/destructors.cpp === --- test/CodeGenCXX/destructors.cpp +++ test/CodeGenCXX/destructors.cpp @@ -4,6 +4,9 @@ // 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: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o - -fcxx-exceptions -fexceptions -O1 -disable-llvm-optzns -std=c++11 > %t2 +// RUN: FileCheck --check-prefix=CHECK6 --input-file=%t2 %s +// REQUIRES: asserts struct A { int a; @@ -428,3 +431,64 @@ 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(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(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(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(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(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(i64 32, i8* [[BC6]]) + + struct S1 { +~S1(); +int a[8]; + }; + + void func1(S1 &)
Re: [PATCH] D18196: [CodeGen] Emit lifetime.end intrinsic after destructor call in landing pad
ahatanak added a comment. In http://reviews.llvm.org/D18196#375997, @rjmccall wrote: > You should also check that any back-end peepholes we have in place (null type > infos to signify a call-terminate landingpad?) aren't disturbed by the > lifetime intrinsics. I looked at the back-end passes that might be affected by the insertion of lifetime markers. I don't think inserting lifetime markers will have an adverse effect on any of the back-end code-generation. http://reviews.llvm.org/D18196 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D18196: [CodeGen] Emit lifetime.end intrinsic after destructor call in landing pad
ahatanak updated this revision to Diff 51376. ahatanak added a comment. Added a test in test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp to check expected patterns are emitted. http://reviews.llvm.org/D18196 Files: lib/CodeGen/CGCleanup.cpp lib/CodeGen/CGDecl.cpp lib/CodeGen/EHScopeStack.h test/CodeGenCXX/destructors.cpp test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp Index: test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp === --- test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp +++ test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp @@ -1,4 +1,5 @@ // 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 %s +// RUN: %clang_cc1 -std=c++11 -emit-llvm -O3 -disable-llvm-optzns %s -o - -triple=i386-pc-win32 -mconstructor-aliases -fexceptions -fcxx-exceptions -fno-rtti | FileCheck -check-prefix WIN32 -check-prefix WIN32-LIFETIME %s struct A { A(); @@ -206,3 +207,36 @@ // WIN32: cleanuppad // WIN32: call x86_thiscallcc void @"\01??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 void @"\01?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(i64 1, i8* %[[bc0]]) +// WIN32-LIFETIME: invoke void @"\01?g@lifetime_marker@@YAXXZ"() +// WIN32-LIFETIME-NEXT: to label %[[cont:[^ ]*]] unwind label %[[lpad0:[^ ]*]] +// +// WIN32-LIFETIME: [[cont]]: +// WIN32-LIFETIME: call x86_thiscallcc void @"\01??1C@lifetime_marker@@QAE@XZ"({{.*}}) +// WIN32-LIFETIME: %[[bc1:.*]] = bitcast %"struct.lifetime_marker::C"* %[[c]] to i8* +// WIN32-LIFETIME: call void @llvm.lifetime.end(i64 1, i8* %[[bc1]]) +// +// WIN32-LIFETIME: [[lpad0]]: +// WIN32-LIFETIME-NEXT: cleanuppad +// WIN32-LIFETIME: call x86_thiscallcc void @"\01??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(i64 1, i8* %[[bc2]]) +} Index: test/CodeGenCXX/destructors.cpp === --- test/CodeGenCXX/destructors.cpp +++ test/CodeGenCXX/destructors.cpp @@ -4,6 +4,8 @@ // 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: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o - -fcxx-exceptions -fexceptions -O1 -disable-llvm-optzns -std=c++11 > %t2 +// RUN: FileCheck --check-prefix=CHECK6 --input-file=%t2 %s struct A { int a; @@ -428,3 +430,64 @@ 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(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(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(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(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(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(i64 32, i8* [[BC6]]) + + struct S1 { +~S1(); +int a[8]; + }; + + void
Re: [PATCH] D18196: [CodeGen] Emit lifetime.end intrinsic after destructor call in landing pad
rnk added a comment. In http://reviews.llvm.org/D18196#376837, @ahatanak wrote: > I can add another RUN line to test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp > that is identical to the existing RUN line except that it has "-O3 > -disable-llvm-optzns". I confirmed that the test still passes without any > changes to the test itself. > > Is that what you are looking for? I assumed the test wouldn't pass with those flags, but yes, that works. Could you add the obvious CHECK lines for a simple cleanup though? There should be an invoke, two cleanuppads, one calls the dtor, the other ends the lifetime, they chain to each other. http://reviews.llvm.org/D18196 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D18196: [CodeGen] Emit lifetime.end intrinsic after destructor call in landing pad
rnk added a comment. In http://reviews.llvm.org/D18196#375997, @rjmccall wrote: > You should talk to Reid or someone else involved in MSVC-style EH support to > ensure that they generate a reasonable code pattern for this. I patched this in and verified it works. Clang makes a separate funclet for the lifetime end, which is suboptimal, but LLVM knows how to simplify it down to one. The stack coloring optimization in the backend doesn't fire yet, though. =/ Can you add a simple test for this? Make something similar to test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp but with optimizations enabled. http://reviews.llvm.org/D18196 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D18196: [CodeGen] Emit lifetime.end intrinsic after destructor call in landing pad
rjmccall added a comment. You should talk to Reid or someone else involved in MSVC-style EH support to ensure that they generate a reasonable code pattern for this. You should also check that any back-end peepholes we have in place (null type infos to signify a call-terminate landingpad?) aren't disturbed by the lifetime intrinsics. http://reviews.llvm.org/D18196 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits