From 7c5275a0f146faa2127526eba9ecb58ea1935ced Mon Sep 17 00:00:00 2001 From: Marvin Greenberg Date: Thu, 30 Jan 2014 16:17:30 -0500 Subject: [PATCH 1/8] Make sure tests are built with same stdlib flag as used to configure swig --- Examples/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Examples/Makefile.in b/Examples/Makefile.in index fc17d8784..7680908ab 100644 --- a/Examples/Makefile.in +++ b/Examples/Makefile.in @@ -25,7 +25,7 @@ TARGET = CC = @CC@ CXX = @CXX@ CFLAGS = @PLATCFLAGS@ -CXXFLAGS = @BOOST_CPPFLAGS@ @PLATCXXFLAGS@ +CXXFLAGS = @BOOST_CPPFLAGS@ @PLATCXXFLAGS@ $(filter -stdlib%,@CXXFLAGS@) prefix = @prefix@ exec_prefix= @exec_prefix@ SRCS = From 9fd42e0e67701795e3b9017084e36298158ef39b Mon Sep 17 00:00:00 2001 From: Marvin Greenberg Date: Thu, 30 Jan 2014 16:18:21 -0500 Subject: [PATCH 2/8] Work around clang bugs with symbol resolution --- Examples/test-suite/nested_scope.i | 12 +++- ..._using_directive_and_declaration_forward.i | 58 ++++++++++++++++++ .../using_directive_and_declaration_forward.i | 60 +++++++++++++++++++ 3 files changed, 129 insertions(+), 1 deletion(-) diff --git a/Examples/test-suite/nested_scope.i b/Examples/test-suite/nested_scope.i index 358dbbb61..04945a7b6 100644 --- a/Examples/test-suite/nested_scope.i +++ b/Examples/test-suite/nested_scope.i @@ -3,12 +3,22 @@ %inline %{ namespace ns { struct Global { +#ifdef __clang__ + struct Outer { + struct Nested; + struct Nested { + int data; + }; + }; + struct Outer::Nested instance; +#else struct Outer { struct Nested; }; struct Outer::Nested { int data; } instance; +#endif }; } -%} \ No newline at end of file +%} diff --git a/Examples/test-suite/template_using_directive_and_declaration_forward.i b/Examples/test-suite/template_using_directive_and_declaration_forward.i index a5a7fbf31..dcc1d6ab4 100644 --- a/Examples/test-suite/template_using_directive_and_declaration_forward.i +++ b/Examples/test-suite/template_using_directive_and_declaration_forward.i @@ -9,7 +9,15 @@ namespace Outer1 { } using namespace Outer1::Space1; using Outer1::Space1::Thing1; +#ifdef __clang__ +namespace Outer1 { + namespace Space1 { + template class Thing1 {}; + } +} +#else template class Thing1 {}; +#endif void useit1(Thing1 t) {} void useit1a(Outer1::Space1::Thing1 t) {} void useit1b(::Outer1::Space1::Thing1 t) {} @@ -25,7 +33,15 @@ namespace Outer2 { } using namespace Outer2; using Space2::Thing2; +#ifdef __clang__ +namespace Outer2 { + namespace Space2 { + template class Thing2 {}; + } +} +#else template class Thing2 {}; +#endif void useit2(Thing2 t) {} void useit2a(Outer2::Space2::Thing2 t) {} void useit2b(::Outer2::Space2::Thing2 t) {} @@ -45,7 +61,17 @@ namespace Outer3 { using namespace Outer3; using namespace Space3; using Middle3::Thing3; +#ifdef __clang__ +namespace Outer3 { + namespace Space3 { + namespace Middle3 { + template class Thing3 {}; + } + } +} +#else template class Thing3 {}; +#endif void useit3(Thing3 t) {} void useit3a(Outer3::Space3::Middle3::Thing3 t) {} void useit3b(::Outer3::Space3::Middle3::Thing3 t) {} @@ -66,7 +92,17 @@ namespace Outer4 { } using namespace Outer4::Space4; using Middle4::Thing4; +#ifdef __clang__ +namespace Outer4 { + namespace Space4 { + namespace Middle4 { + template class Thing4 {}; + } + } +} +#else template class Thing4 {}; +#endif void useit4(Thing4 t) {} void useit4a(Outer4::Space4::Middle4::Thing4 t) {} void useit4b(::Outer4::Space4::Middle4::Thing4 t) {} @@ -90,7 +126,19 @@ namespace Outer5 { using namespace ::Outer5::Space5; using namespace Middle5; using More5::Thing5; +#ifdef __clang__ +namespace Outer5 { + namespace Space5 { + namespace Middle5 { + namespace More5 { + template class Thing5 {}; + } + } + } +} +#else template class Thing5 {}; +#endif void useit5(Thing5 t) {} void useit5a(Outer5::Space5::Middle5::More5::Thing5 t) {} void useit5b(::Outer5::Space5::Middle5::More5::Thing5 t) {} @@ -109,7 +157,17 @@ namespace Outer7 { } } using namespace Outer7::Space7; +#ifdef __clang__ +namespace Outer7 { + namespace Space7 { + namespace Middle7 { + template class Thing7 {}; + } + } +} +#else template class Middle7::Thing7 {}; +#endif using Middle7::Thing7; void useit7(Thing7 t) {} void useit7a(Outer7::Space7::Middle7::Thing7 t) {} diff --git a/Examples/test-suite/using_directive_and_declaration_forward.i b/Examples/test-suite/using_directive_and_declaration_forward.i index 238b3b77f..1f219e671 100644 --- a/Examples/test-suite/using_directive_and_declaration_forward.i +++ b/Examples/test-suite/using_directive_and_declaration_forward.i @@ -9,7 +9,15 @@ namespace Outer1 { } using namespace Outer1::Space1; using Outer1::Space1::Thing1; +#ifdef __clang__ +namespace Outer1 { + namespace Space1 { + class Thing1 {}; + } +} +#else class Thing1 {}; +#endif void useit1(Thing1 t) {} void useit1a(Outer1::Space1::Thing1 t) {} void useit1b(::Outer1::Space1::Thing1 t) {} @@ -25,7 +33,17 @@ namespace Outer2 { } using namespace Outer2; using Space2::Thing2; +using namespace Outer1::Space1; +using Outer1::Space1::Thing1; +#ifdef __clang__ +namespace Outer2 { + namespace Space2 { + class Thing2 {}; + } +} +#else class Thing2 {}; +#endif void useit2(Thing2 t) {} void useit2a(Outer2::Space2::Thing2 t) {} void useit2b(::Outer2::Space2::Thing2 t) {} @@ -45,7 +63,17 @@ namespace Outer3 { using namespace Outer3; using namespace Space3; using Middle3::Thing3; +#ifdef __clang__ +namespace Outer3 { + namespace Space3 { + namespace Middle3 { + class Thing3 {}; + } + } +} +#else class Thing3 {}; +#endif void useit3(Thing3 t) {} void useit3a(Outer3::Space3::Middle3::Thing3 t) {} void useit3b(::Outer3::Space3::Middle3::Thing3 t) {} @@ -66,7 +94,17 @@ namespace Outer4 { } using namespace Outer4::Space4; using Middle4::Thing4; +#ifdef __clang__ +namespace Outer4 { + namespace Space4 { + namespace Middle4 { + class Thing4 {}; + } + } +} +#else class Thing4 {}; +#endif void useit4(Thing4 t) {} void useit4a(Outer4::Space4::Middle4::Thing4 t) {} void useit4b(::Outer4::Space4::Middle4::Thing4 t) {} @@ -90,7 +128,19 @@ namespace Outer5 { using namespace ::Outer5::Space5; using namespace Middle5; using More5::Thing5; +#ifdef __clang__ +namespace Outer5 { + namespace Space5 { + namespace Middle5 { + namespace More5 { + class Thing5 {}; + } + } + } +} +#else class Thing5 {}; +#endif void useit5(Thing5 t) {} void useit5a(Outer5::Space5::Middle5::More5::Thing5 t) {} void useit5b(::Outer5::Space5::Middle5::More5::Thing5 t) {} @@ -109,7 +159,17 @@ namespace Outer7 { } } using namespace Outer7::Space7; +#ifdef __clang__ +namespace Outer7 { + namespace Space7 { + namespace Middle7 { + class Thing7 {}; + } + } +} +#else class Middle7::Thing7 {}; +#endif using Middle7::Thing7; void useit7(Thing7 t) {} void useit7a(Outer7::Space7::Middle7::Thing7 t) {} From c3eff9234c5aaca49be12758bb6b2cc4dc18623f Mon Sep 17 00:00:00 2001 From: Marvin Greenberg Date: Fri, 31 Jan 2014 16:03:14 -0500 Subject: [PATCH 3/8] Workaround for clang 3.2 libc++ empty struct bug. Certain tests have empty structs or classes. This encounters a bug with clang: http://llvm.org/bugs/show_bug.cgi?id=16764 This is fixed in later versions of clang, but not the version currently bundled with Mavericks and XCode 5 --- Examples/test-suite/constructor_copy.i | 6 ++++-- Examples/test-suite/ignore_template_constructor.i | 10 ++++++---- Examples/test-suite/smart_pointer_inherit.i | 1 + Examples/test-suite/std_containers.i | 3 ++- Examples/test-suite/template_matrix.i | 1 + Examples/test-suite/template_opaque.i | 1 + 6 files changed, 15 insertions(+), 7 deletions(-) diff --git a/Examples/test-suite/constructor_copy.i b/Examples/test-suite/constructor_copy.i index f6bdcb240..bfbd706f4 100644 --- a/Examples/test-suite/constructor_copy.i +++ b/Examples/test-suite/constructor_copy.i @@ -94,14 +94,16 @@ public: namespace Space { class Flow { +int x; public: - Flow(int i) {} + Flow(int i) : x(i) {} }; class FlowFlow { +int x; public: - FlowFlow(int i) {} + FlowFlow(int i) : x(i) {} }; } diff --git a/Examples/test-suite/ignore_template_constructor.i b/Examples/test-suite/ignore_template_constructor.i index ffd541986..31a5505fb 100644 --- a/Examples/test-suite/ignore_template_constructor.i +++ b/Examples/test-suite/ignore_template_constructor.i @@ -17,9 +17,10 @@ #if defined(SWIG_GOOD_VECTOR) %inline %{ class Flow { - Flow() {} +double x; + Flow():x(0.0) {} public: - Flow(double d) {} + Flow(double d) : x(d) {} }; %} @@ -28,9 +29,10 @@ public: %inline %{ class Flow { +double x; public: - Flow() {} - Flow(double d) {} + Flow(): x(0.0) {} + Flow(double d) : x(d) {} }; %} diff --git a/Examples/test-suite/smart_pointer_inherit.i b/Examples/test-suite/smart_pointer_inherit.i index a81d72268..52df5a92b 100644 --- a/Examples/test-suite/smart_pointer_inherit.i +++ b/Examples/test-suite/smart_pointer_inherit.i @@ -47,6 +47,7 @@ %inline %{ class ItkLevelSetNodeUS2 { + int x; }; %} diff --git a/Examples/test-suite/std_containers.i b/Examples/test-suite/std_containers.i index 0955226ad..ae69b6418 100644 --- a/Examples/test-suite/std_containers.i +++ b/Examples/test-suite/std_containers.i @@ -191,7 +191,8 @@ template struct Param struct Foo { - Foo(int i) { + int x; + Foo(int i) : x(i) { } }; diff --git a/Examples/test-suite/template_matrix.i b/Examples/test-suite/template_matrix.i index 27696542a..535193819 100644 --- a/Examples/test-suite/template_matrix.i +++ b/Examples/test-suite/template_matrix.i @@ -21,6 +21,7 @@ namespace simuPOP template class Operator { + int x; }; } diff --git a/Examples/test-suite/template_opaque.i b/Examples/test-suite/template_opaque.i index 5918fe069..b910e47e3 100644 --- a/Examples/test-suite/template_opaque.i +++ b/Examples/test-suite/template_opaque.i @@ -6,6 +6,7 @@ { struct OpaqueStruct { + int x; }; } From 213774e0b63810b318bbaaa577e10a3de02263d5 Mon Sep 17 00:00:00 2001 From: Marvin Greenberg Date: Mon, 3 Feb 2014 11:34:55 -0500 Subject: [PATCH 4/8] Fix issue on clang about implicit instantiation of undefined template Generated code does not include , which is referenced in templates. Clang may be incorrectly or aggresively instantiating some template. E.g., import_stl_b_wrap.cxx:3199:51: error: implicit instantiation of undefined template 'std::__1::basic_string --- Lib/std/std_common.i | 8 +++++++- Lib/typemaps/traits.swg | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/Lib/std/std_common.i b/Lib/std/std_common.i index 7c52880e9..cb91bc632 100644 --- a/Lib/std/std_common.i +++ b/Lib/std/std_common.i @@ -73,7 +73,13 @@ namespace std { #endif %} -%fragment("StdTraitsCommon","header") %{ +%fragment("StdStringInclude","header") %{ +#ifdef __clang__ +#include +#endif +%} + +%fragment("StdTraitsCommon","header",fragment="StdStringInclude") %{ namespace swig { template struct noconst_traits { diff --git a/Lib/typemaps/traits.swg b/Lib/typemaps/traits.swg index b39eb3946..584d480c2 100644 --- a/Lib/typemaps/traits.swg +++ b/Lib/typemaps/traits.swg @@ -26,7 +26,13 @@ #include %} -%fragment("Traits","header") +%fragment("StdStringInclude","header") %{ +#ifdef __clang__ +#include +#endif +%} + +%fragment("Traits","header",fragment="StdStringInclude") { namespace swig { /* From 843aa7cd65985319a64d4f1297778f93f96a5008 Mon Sep 17 00:00:00 2001 From: Marvin Greenberg Date: Thu, 30 Jan 2014 16:37:07 -0500 Subject: [PATCH 5/8] Work around differences in clang libc++ std::vector::const_reference clang++ using -stdlib=libc++ defines const_reference as a class, to map boolean vectors onto a bit set. Because swig does not "see" the type as "const &" it generates incorrect code for this case, generating a declaration like: const_reference result; When const_reference is a typedef to 'bool' as is the case with stdlibc++ this works. When this is actually a constant reference, this is clearly invalid since it is not initialized. For libc++, this is a class which cannot be default constructed, resulting in an error. The fix is to explicitly define the various accessor extensions as having a bool return type for this specialization. --- Lib/csharp/std_vector.i | 2 +- Lib/d/std_vector.i | 12 ++++++------ Lib/go/std_vector.i | 2 +- Lib/java/std_vector.i | 2 +- Lib/php/std_vector.i | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Lib/csharp/std_vector.i b/Lib/csharp/std_vector.i index 9d52a962b..467a2ade8 100644 --- a/Lib/csharp/std_vector.i +++ b/Lib/csharp/std_vector.i @@ -217,7 +217,7 @@ else throw std::out_of_range("index"); } - const_reference getitem(int index) throw (std::out_of_range) { + CONST_REFERENCE getitem(int index) throw (std::out_of_range) { if (index>=0 && index<(int)$self->size()) return (*$self)[index]; else diff --git a/Lib/d/std_vector.i b/Lib/d/std_vector.i index b7d4e223f..50942f289 100644 --- a/Lib/d/std_vector.i +++ b/Lib/d/std_vector.i @@ -128,7 +128,7 @@ public void capacity(size_t value) { return $self->capacity() - $self->size(); } - const_reference remove() throw (std::out_of_range) { + CONST_REFERENCE remove() throw (std::out_of_range) { if ($self->empty()) { throw std::out_of_range("Tried to remove last element from empty vector."); } @@ -138,7 +138,7 @@ public void capacity(size_t value) { return value; } - const_reference remove(size_type index) throw (std::out_of_range) { + CONST_REFERENCE remove(size_type index) throw (std::out_of_range) { if (index >= $self->size()) { throw std::out_of_range("Tried to remove element with invalid index."); } @@ -153,7 +153,7 @@ public void capacity(size_t value) { // Wrappers for setting/getting items with the possibly thrown exception // specified (important for SWIG wrapper generation). %extend { - const_reference getElement(size_type index) throw (std::out_of_range) { + CONST_REFERENCE getElement(size_type index) throw (std::out_of_range) { if ((index < 0) || ($self->size() <= index)) { throw std::out_of_range("Tried to get value of element with invalid index."); } @@ -464,7 +464,7 @@ int opApply(int delegate(ref size_t index, ref $typemap(dtype, CTYPE) value) dg) return pv; } - const_reference remove() throw (std::out_of_range) { + CONST_REFERENCE remove() throw (std::out_of_range) { if ($self->empty()) { throw std::out_of_range("Tried to remove last element from empty vector."); } @@ -474,7 +474,7 @@ int opApply(int delegate(ref size_t index, ref $typemap(dtype, CTYPE) value) dg) return value; } - const_reference remove(size_type index) throw (std::out_of_range) { + CONST_REFERENCE remove(size_type index) throw (std::out_of_range) { if (index >= $self->size()) { throw std::out_of_range("Tried to remove element with invalid index."); } @@ -506,7 +506,7 @@ int opApply(int delegate(ref size_t index, ref $typemap(dtype, CTYPE) value) dg) // Wrappers for setting/getting items with the possibly thrown exception // specified (important for SWIG wrapper generation). %extend { - const_reference getElement(size_type index) throw (std::out_of_range) { + CONST_REFERENCE getElement(size_type index) throw (std::out_of_range) { if ((index < 0) || ($self->size() <= index)) { throw std::out_of_range("Tried to get value of element with invalid index."); } diff --git a/Lib/go/std_vector.i b/Lib/go/std_vector.i index f4ce8431c..29bcd1391 100644 --- a/Lib/go/std_vector.i +++ b/Lib/go/std_vector.i @@ -59,7 +59,7 @@ namespace std { %rename(add) push_back; void push_back(const value_type& x); %extend { - const_reference get(int i) throw (std::out_of_range) { + bool get(int i) throw (std::out_of_range) { int size = int(self->size()); if (i>=0 && isize()); if (i>=0 && ipop_back(); return x; } - const_reference get(int i) throw (std::out_of_range) { + bool get(int i) throw (std::out_of_range) { int size = int(self->size()); if (i>=0 && i Date: Wed, 5 Feb 2014 15:18:51 -0800 Subject: [PATCH 6/8] Move setting required -stdlib argument into configure.ac --- Examples/Makefile.in | 2 +- configure.ac | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/Examples/Makefile.in b/Examples/Makefile.in index 7680908ab..fc17d8784 100644 --- a/Examples/Makefile.in +++ b/Examples/Makefile.in @@ -25,7 +25,7 @@ TARGET = CC = @CC@ CXX = @CXX@ CFLAGS = @PLATCFLAGS@ -CXXFLAGS = @BOOST_CPPFLAGS@ @PLATCXXFLAGS@ $(filter -stdlib%,@CXXFLAGS@) +CXXFLAGS = @BOOST_CPPFLAGS@ @PLATCXXFLAGS@ prefix = @prefix@ exec_prefix= @exec_prefix@ SRCS = diff --git a/configure.ac b/configure.ac index 03677f90d..d05eb1802 100644 --- a/configure.ac +++ b/configure.ac @@ -352,6 +352,15 @@ if test x"$enable_cpp11_testing" = xyes; then fi fi +# On darwin before Mavericks when using clang, need to ensure using +# libc++ for tests and examples to run under mono +case $host in + *-*-darwin*) if test "$CXX" = "clang++"; + then PLATCXXFLAGS="$PLATCXXFLAGS -stdlib=libc++" + fi;; + *) ;; +esac + # Set info about shared libraries. AC_SUBST(SO) AC_SUBST(LDSHARED) From fd85d12a2cd5dc31e6f9a0d0a29bfd61bd8865f4 Mon Sep 17 00:00:00 2001 From: Marvin Greenberg Date: Wed, 5 Feb 2014 15:31:57 -0800 Subject: [PATCH 7/8] Allow csharp examples to run under mono --- Examples/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Examples/Makefile.in b/Examples/Makefile.in index fc17d8784..dac3f2c37 100644 --- a/Examples/Makefile.in +++ b/Examples/Makefile.in @@ -1205,7 +1205,7 @@ CSHARPCOMPILER = @CSHARPCOMPILER@ CSHARPCILINTERPRETER = @CSHARPCILINTERPRETER@ CSHARPCFLAGS = @CSHARPCFLAGS@ CSHARPSO = @CSHARPSO@ -CSHARP_RUNME = ./$(RUNME).exe +CSHARP_RUNME = $(CSHARPCILINTERPRETER) ./$(RUNME).exe # ---------------------------------------------------------------- # Build a CSharp dynamically loadable module (C) From d35af986468da6f61d5a660f13b260810323fb55 Mon Sep 17 00:00:00 2001 From: Marvin Greenberg Date: Wed, 12 Feb 2014 14:16:43 -0500 Subject: [PATCH 8/8] Change to only add -stdlib on OSX versions that have libc++ Use better test for clang --- configure.ac | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index d05eb1802..aead05c21 100644 --- a/configure.ac +++ b/configure.ac @@ -352,10 +352,14 @@ if test x"$enable_cpp11_testing" = xyes; then fi fi -# On darwin before Mavericks when using clang, need to ensure using -# libc++ for tests and examples to run under mono +# On darwin 10.7,10.8,10.9 using clang++, need to ensure using +# libc++ for tests and examples to run under mono. May affect +# other language targets as well - problem is an OSX incompatibility +# between libraries depending on libstdc++ and libc++. +CLANGXX= +$CXX -v 2>&1 | grep -i clang >/dev/null && CLANGXX=yes case $host in - *-*-darwin*) if test "$CXX" = "clang++"; + *-*-darwin11* | *-*-darwin12* |*-*-darwin13* ) if test "$CLANGXX" = "yes"; then PLATCXXFLAGS="$PLATCXXFLAGS -stdlib=libc++" fi;; *) ;;