diff options
author | Rohan McGovern <rohan.mcgovern@nokia.com> | 2009-08-12 05:03:27 (GMT) |
---|---|---|
committer | Rohan McGovern <rohan.mcgovern@nokia.com> | 2009-08-12 05:18:15 (GMT) |
commit | de8328017516abbe133dc2304bfea5fad5474da3 (patch) | |
tree | 039f0af4d88014bb1ab231ee2c0fcb9de5a26e24 /tests/auto/compiler/tst_compiler.cpp | |
parent | 265cb525256be8e6d39058b6427f46e1ae381907 (diff) | |
download | Qt-de8328017516abbe133dc2304bfea5fad5474da3.zip Qt-de8328017516abbe133dc2304bfea5fad5474da3.tar.gz Qt-de8328017516abbe133dc2304bfea5fad5474da3.tar.bz2 |
Test naming convention fixes.
Make sure the testcase and directory name are the same
(excluding `tst_').
Diffstat (limited to 'tests/auto/compiler/tst_compiler.cpp')
-rw-r--r-- | tests/auto/compiler/tst_compiler.cpp | 656 |
1 files changed, 656 insertions, 0 deletions
diff --git a/tests/auto/compiler/tst_compiler.cpp b/tests/auto/compiler/tst_compiler.cpp new file mode 100644 index 0000000..78c1a56 --- /dev/null +++ b/tests/auto/compiler/tst_compiler.cpp @@ -0,0 +1,656 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include <QtCore/QtCore> +#include <QtTest/QtTest> + +#include <algorithm> + +#define BASECLASS_NOT_ABSTRACT +#include "baseclass.h" +#include "derivedclass.h" + +QT_USE_NAMESPACE + +class tst_Compiler : public QObject +{ +Q_OBJECT + +private slots: + void template_methods(); + void template_constructors(); + void template_subclasses(); + void methodSpecialization(); + void constructorSpecialization(); + void staticTemplateMethods(); + void staticTemplateMethodSpecialization(); + void detectDataStream(); + void detectEnums(); + void overrideCFunction(); + void stdSortQList(); + void stdSortQVector(); + void templateCallOrder(); + void virtualFunctionNoLongerPureVirtual(); + void charSignedness() const; + void privateStaticTemplateMember() const; + void staticConstUnionWithInitializerList() const; +}; + +#if defined(Q_CC_MSVC) && _MSC_VER < 1300 +#define MSVC6 +#endif + +#if defined(Q_CC_MSVC) && _MSC_VER == 1300 +#define MSVC2002 +#endif + +#if defined(MSVC6) +# define DONT_TEST_TEMPLATE_METHODS +# define DONT_TEST_TEMPLATE_CONSTRUCTORS +# define DONT_TEST_METHOD_SPECIALIZATION +# define DONT_TEST_CONSTRUCTOR_SPECIALIZATION +# define DONT_TEST_STATIC_TEMPLATE_METHODS +# define DONT_TEST_STATIC_TEMPLATE_METHOD_SPECIALIZATION +# define DONT_TEST_STL_SORTING +# define DONT_TEST_SIGNEDNESS +#endif + +#if defined(MSVC2002) +# define DONT_TEST_TEMPLATE_METHODS +# define DONT_TEST_DETECT_ENUMS +# define DONT_TEST_METHOD_SPECIALIZATION +# define DONT_TEST_CONSTRUCTOR_SPECIALIZATION +# define DONT_TEST_STATIC_TEMPLATE_METHOD_SPECIALIZATION +# define DONT_TEST_STL_SORTING +#endif + +#if defined(Q_CC_HPACC) +# define DONT_TEST_TEMPLATE_CONSTRUCTORS +# define DONT_TEST_CONSTRUCTOR_SPECIALIZATION +# define DONT_TEST_DATASTREAM_DETECTION +#endif + +#if defined(Q_CC_SUN) +# define DONT_TEST_STL_SORTING +#endif + +#ifndef DONT_TEST_TEMPLATE_METHODS +class TemplateMethodClass +{ +public: + template <class T> + T foo() { return 42; } +}; + +void tst_Compiler::template_methods() +{ + TemplateMethodClass t; + + QCOMPARE(t.foo<int>(), 42); + QCOMPARE(t.foo<long>(), 42l); + QCOMPARE(t.foo<double>(), 42.0); +} +#else +void tst_Compiler::template_methods() +{ QSKIP("Compiler doesn't do template methods", SkipAll); } +#endif + +#ifndef DONT_TEST_TEMPLATE_CONSTRUCTORS +class TemplateConstructorClass +{ +public: + template <class T> + TemplateConstructorClass(const T& t) { i = int(t); } + + int i; +}; + +void tst_Compiler::template_constructors() +{ + TemplateConstructorClass t1(42); + TemplateConstructorClass t2(42l); + TemplateConstructorClass t3(42.0); + + QCOMPARE(t1.i, 42); + QCOMPARE(t2.i, 42); + QCOMPARE(t3.i, 42); +} +#else +void tst_Compiler::template_constructors() +{ QSKIP("Compiler doesn't do template constructors", SkipAll); } +#endif + +template <typename T> +struct OuterClass +{ + template <typename U> + struct InnerClass + { + U convert(const T &t) { return static_cast<U>(t); } + }; +}; + +void tst_Compiler::template_subclasses() +{ + OuterClass<char>::InnerClass<int> c1; + QCOMPARE(c1.convert('a'), int('a')); + + OuterClass<QRect>::InnerClass<QRectF> c2; + QCOMPARE(c2.convert(QRect(1, 2, 3, 4)), QRectF(QRect(1, 2, 3, 4))); +} + +#ifndef DONT_TEST_METHOD_SPECIALIZATION +class TemplateMethodClass2 +{ +public: + template <class T> + T foo() { return 42; } +}; + +template<> +int TemplateMethodClass2::foo<int>() +{ return 43; } + +void tst_Compiler::methodSpecialization() +{ + TemplateMethodClass2 t; + + QCOMPARE(t.foo<int>(), 43); + QCOMPARE(t.foo<long>(), 42l); + QCOMPARE(t.foo<double>(), 42.0); +} +#else +void tst_Compiler::methodSpecialization() +{ QSKIP("Compiler doesn't do template specialization", SkipAll); } +#endif + +#ifndef DONT_TEST_CONSTRUCTOR_SPECIALIZATION +class TemplateConstructorClass2 +{ +public: + template <class T> + TemplateConstructorClass2(const T &t) { i = int(t); } + + int i; +}; + +template<> +TemplateConstructorClass2::TemplateConstructorClass2(const int &t) { i = t + 1; } + +void tst_Compiler::constructorSpecialization() +{ + TemplateConstructorClass2 t1(42); + TemplateConstructorClass2 t2(42l); + TemplateConstructorClass2 t3(42.0); + + QCOMPARE(t1.i, 43); + QCOMPARE(t2.i, 42); + QCOMPARE(t3.i, 42); +} +#else +void tst_Compiler::constructorSpecialization() +{ QSKIP("Compiler doesn't do constructor specialization", SkipAll); } +#endif + +#ifndef DONT_TEST_STATIC_TEMPLATE_METHODS +class StaticTemplateClass +{ +public: + template <class T> + static T foo() { return 42; } +}; + +void tst_Compiler::staticTemplateMethods() +{ + QCOMPARE(StaticTemplateClass::foo<int>(), 42); + QCOMPARE(StaticTemplateClass::foo<uint>(), 42u); +} +#else +void tst_Compiler::staticTemplateMethods() +{ QSKIP("Compiler doesn't do static template methods", SkipAll); } +#endif + +#ifndef DONT_TEST_STATIC_TEMPLATE_METHOD_SPECIALIZATION +class StaticTemplateClass2 +{ +public: + template <class T> + static T foo() { return 42; } +}; + +template<> +double StaticTemplateClass2::foo<double>() { return 18.5; } + +void tst_Compiler::staticTemplateMethodSpecialization() +{ + QCOMPARE(StaticTemplateClass2::foo<int>(), 42); + QCOMPARE(StaticTemplateClass2::foo<uint>(), 42u); + QCOMPARE(StaticTemplateClass2::foo<double>(), 18.5); +} +#else +void tst_Compiler::staticTemplateMethodSpecialization() +{ QSKIP("Compiler doesn't do static template method specialization", SkipAll); } +#endif + +#ifndef DONT_TEST_DATASTREAM_DETECTION +/******* DataStream tester *********/ +namespace QtTestInternal +{ + struct EmptyStruct {}; + struct LowPreferenceStruct { LowPreferenceStruct(...); }; + + EmptyStruct operator<<(QDataStream &, const LowPreferenceStruct &); + EmptyStruct operator>>(QDataStream &, const LowPreferenceStruct &); + + template<typename T> + struct DataStreamChecker + { + static EmptyStruct hasStreamHelper(const EmptyStruct &); + static QDataStream hasStreamHelper(const QDataStream &); + static QDataStream &dsDummy(); + static T &dummy(); + +#ifdef BROKEN_COMPILER + static const bool HasDataStream = + sizeof(hasStreamHelper(dsDummy() << dummy())) == sizeof(QDataStream) + && sizeof(hasStreamHelper(dsDummy() >> dummy())) == sizeof(QDataStream); +#else + enum { + HasOutDataStream = sizeof(hasStreamHelper(dsDummy() >> dummy())) == sizeof(QDataStream), + HasInDataStream = sizeof(hasStreamHelper(dsDummy() << dummy())) == sizeof(QDataStream), + HasDataStream = HasOutDataStream & HasInDataStream + }; +#endif + }; + + template<bool> + struct DataStreamOpHelper + { + template <typename T> + struct Getter { + static QMetaType::SaveOperator saveOp() { return 0; } + }; + }; + + template<> + struct DataStreamOpHelper<true> + { + template <typename T> + struct Getter { + static QMetaType::SaveOperator saveOp() + { + typedef void(*SavePtr)(QDataStream &, const T *); + SavePtr op = ::qMetaTypeSaveHelper<T>; + return reinterpret_cast<QMetaType::SaveOperator>(op); + } + }; + + }; + + template<typename T> + inline QMetaType::SaveOperator getSaveOperator(T * = 0) + { + typedef typename DataStreamOpHelper<DataStreamChecker<T>::HasDataStream>::template Getter<T> GetterHelper; + return GetterHelper::saveOp(); + } +}; + +struct MyString: public QString {}; +struct Qxxx {}; + +void tst_Compiler::detectDataStream() +{ + QVERIFY(QtTestInternal::DataStreamChecker<int>::HasDataStream == true); + QVERIFY(QtTestInternal::DataStreamChecker<uint>::HasDataStream == true); + QVERIFY(QtTestInternal::DataStreamChecker<char *>::HasDataStream == true); + QVERIFY(QtTestInternal::DataStreamChecker<const int>::HasInDataStream == true); + QVERIFY(QtTestInternal::DataStreamChecker<const int>::HasOutDataStream == false); + QVERIFY(QtTestInternal::DataStreamChecker<const int>::HasDataStream == false); + QVERIFY(QtTestInternal::DataStreamChecker<double>::HasDataStream == true); + + QVERIFY(QtTestInternal::DataStreamChecker<QString>::HasDataStream == true); + QVERIFY(QtTestInternal::DataStreamChecker<MyString>::HasDataStream == true); + QVERIFY(QtTestInternal::DataStreamChecker<Qxxx>::HasDataStream == false); + + QVERIFY(QtTestInternal::getSaveOperator<int>() != 0); + QVERIFY(QtTestInternal::getSaveOperator<uint>() != 0); + QVERIFY(QtTestInternal::getSaveOperator<char *>() != 0); + QVERIFY(QtTestInternal::getSaveOperator<double>() != 0); + QVERIFY(QtTestInternal::getSaveOperator<QString>() != 0); + QVERIFY(QtTestInternal::getSaveOperator<MyString>() != 0); + QVERIFY(QtTestInternal::getSaveOperator<Qxxx>() == 0); +} +#else +void tst_Compiler::detectDataStream() +{ QSKIP("Compiler doesn't evaluate templates correctly", SkipAll); } +#endif + +#ifndef DONT_TEST_DETECT_ENUMS +enum Enum1 { Foo = 0, Bar = 1 }; +enum Enum2 {}; +enum Enum3 { Something = 1 }; + +template <typename T> char QTypeInfoEnumHelper(T); +template <typename T> void *QTypeInfoEnumHelper(...); + +#if defined(MSVC6) + +template <int> +struct QTestTypeInfoHelper +{ + enum { IsE = 0 }; +}; + +template <> +struct QTestTypeInfoHelper<sizeof(void *)> +{ + enum { IsE = 1 }; +}; + + +template <typename T> +struct QTestTypeInfo +{ + typedef typename QTestTypeInfoHelper<sizeof(QTypeInfoEnumHelper<T>(0))> TIHelper; + enum { IsEnum = TIHelper::IsE }; +}; +#else +template <typename T> +struct QTestTypeInfo +{ + enum { IsEnum = sizeof(QTypeInfoEnumHelper<T>(0)) == sizeof(void*) }; +}; +#endif + +void tst_Compiler::detectEnums() +{ + QVERIFY(QTestTypeInfo<Enum1>::IsEnum); + QVERIFY(QTestTypeInfo<Enum2>::IsEnum); + QVERIFY(QTestTypeInfo<Enum3>::IsEnum); + QVERIFY(!QTestTypeInfo<int>::IsEnum); + QVERIFY(!QTestTypeInfo<char>::IsEnum); + QVERIFY(!QTestTypeInfo<uint>::IsEnum); + QVERIFY(!QTestTypeInfo<short>::IsEnum); + QVERIFY(!QTestTypeInfo<ushort>::IsEnum); + QVERIFY(!QTestTypeInfo<void*>::IsEnum); + QVERIFY(!QTestTypeInfo<QString>::IsEnum); + QVERIFY(QTestTypeInfo<Qt::Key>::IsEnum); + QVERIFY(QTestTypeInfo<Qt::ToolBarArea>::IsEnum); + QVERIFY(!QTestTypeInfo<Qt::ToolBarAreas>::IsEnum); + QVERIFY(QTestTypeInfo<Qt::MatchFlag>::IsEnum); + QVERIFY(!QTestTypeInfo<Qt::MatchFlags>::IsEnum); +} +#else +void tst_Compiler::detectEnums() +{ QSKIP("Compiler doesn't evaluate templates correctly", SkipAll); } +#endif + +static int indicator = 0; + + +// this is a silly C function +extern "C" { + void someCFunc(void *) { indicator = 42; } +} + +// this is the catch-template that will be called if the C function doesn't exist +template <typename T> +void someCFunc(T *) { indicator = 10; } + +void tst_Compiler::overrideCFunction() +{ + someCFunc((void*)0); + QCOMPARE(indicator, 42); +} + +#ifndef DONT_TEST_STL_SORTING +void tst_Compiler::stdSortQList() +{ + QList<int> list; + list << 4 << 2; + std::sort(list.begin(), list.end()); + QCOMPARE(list.value(0), 2); + QCOMPARE(list.value(1), 4); + + QList<QString> slist; + slist << "b" << "a"; + std::sort(slist.begin(), slist.end()); + QCOMPARE(slist.value(0), QString("a")); + QCOMPARE(slist.value(1), QString("b")); +} + +void tst_Compiler::stdSortQVector() +{ + QVector<int> vector; + vector << 4 << 2; + std::sort(vector.begin(), vector.end()); + QCOMPARE(vector.value(0), 2); + QCOMPARE(vector.value(1), 4); + + QVector<QString> strvec; + strvec << "b" << "a"; + std::sort(strvec.begin(), strvec.end()); + QCOMPARE(strvec.value(0), QString("a")); + QCOMPARE(strvec.value(1), QString("b")); +} +#else +void tst_Compiler::stdSortQList() +{ QSKIP("Compiler's STL broken", SkipAll); } +void tst_Compiler::stdSortQVector() +{ QSKIP("Compiler's STL broken", SkipAll); } +#endif + +// the C func will set it to 1, the template to 2 +static int whatWasCalled = 0; + +void callOrderFunc(void *) +{ + whatWasCalled = 1; +} + +template <typename T> +void callOrderFunc(T *) +{ + whatWasCalled = 2; +} + +template <typename T> +void callOrderNoCFunc(T *) +{ + whatWasCalled = 3; +} + +/* + This test will check what will get precendence - the C function + or the template. + + It also makes sure this template "override" will compile on all systems + and not result in ambiguities. +*/ +void tst_Compiler::templateCallOrder() +{ + QCOMPARE(whatWasCalled, 0); + + // call it with a void * + void *f = 0; + callOrderFunc(f); + QCOMPARE(whatWasCalled, 1); + whatWasCalled = 0; + + char *c = 0; + /* call it with a char * - AMBIGOUS, fails on several compilers + callOrderFunc(c); + QCOMPARE(whatWasCalled, 1); + whatWasCalled = 0; + */ + + // now try the case when there is no C function + callOrderNoCFunc(f); + QCOMPARE(whatWasCalled, 3); + whatWasCalled = 0; + + callOrderNoCFunc(c); + QCOMPARE(whatWasCalled, 3); + whatWasCalled = 0; +} + +// test to see if removing =0 from a pure virtual function is BC +void tst_Compiler::virtualFunctionNoLongerPureVirtual() +{ +#ifdef BASECLASS_NOT_ABSTRACT + // has a single virtual function, not pure virtual, can call it + BaseClass baseClass; + QTest::ignoreMessage(QtDebugMsg, "BaseClass::wasAPureVirtualFunction()"); + baseClass.wasAPureVirtualFunction(); +#endif + + // DerivedClass inherits from BaseClass, and function is declared + // pure virtual, make sure we can still call it + DerivedClass derivedClass; + QTest::ignoreMessage(QtDebugMsg, "DerivedClass::wasAPureVirtualFunction()"); + derivedClass.wasAPureVirtualFunction(); +} + +template<typename T> const char *resolveCharSignedness(); + +template<> +const char *resolveCharSignedness<char>() +{ + return "char"; +} + +template<> +const char *resolveCharSignedness<unsigned char>() +{ + return "unsigned char"; +} + +template<> +const char *resolveCharSignedness<signed char>() +{ + return "signed char"; +} + +void tst_Compiler::charSignedness() const +{ +#ifdef DONT_TEST_SIGNEDNESS + QSKIP("MS VC 6.0 instantiates the char function for type unsigned char.", SkipSingle); +#else + QCOMPARE("char", resolveCharSignedness<char>()); + QCOMPARE("unsigned char", resolveCharSignedness<unsigned char>()); + QCOMPARE("signed char", resolveCharSignedness<signed char>()); +#endif +} + +class PrivateStaticTemplateMember +{ +public: + long regularMember() + { + return helper<long, int>(3); + } + +private: + template<typename A, typename B> + static A helper(const B b) + { + return A(b); + } +}; + +void tst_Compiler::privateStaticTemplateMember() const +{ + PrivateStaticTemplateMember v; + + QCOMPARE(long(3), v.regularMember()); +} + + +#if !defined(Q_CC_MIPS) + +// make sure we can use a static initializer with a union and then use +// the second member of the union +static const union { unsigned char c[8]; double d; } qt_be_inf_bytes = { { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 } }; +static const union { unsigned char c[8]; double d; } qt_le_inf_bytes = { { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f } }; +static const union { unsigned char c[8]; double d; } qt_armfpa_inf_bytes = { { 0, 0, 0xf0, 0x7f, 0, 0, 0, 0 } }; +static inline double qt_inf() +{ +#ifdef QT_ARMFPA + return qt_armfpa_inf_bytes.d; +#else + return (QSysInfo::ByteOrder == QSysInfo::BigEndian + ? qt_be_inf_bytes.d + : qt_le_inf_bytes.d); +#endif +} + +#else + +static const unsigned char qt_be_inf_bytes[] = { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 }; +static const unsigned char qt_le_inf_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f }; +static const unsigned char qt_armfpa_inf_bytes[] = { 0, 0, 0xf0, 0x7f, 0, 0, 0, 0 }; +static inline double qt_inf() +{ + const uchar *bytes; +#ifdef QT_ARMFPA + bytes = qt_armfpa_inf_bytes; +#else + bytes = (QSysInfo::ByteOrder == QSysInfo::BigEndian + ? qt_be_inf_bytes + : qt_le_inf_bytes); +#endif + + union { uchar c[8]; double d; } returnValue; + qMemCopy(returnValue.c, bytes, sizeof(returnValue.c)); + return returnValue.d; +} + +#endif + +void tst_Compiler::staticConstUnionWithInitializerList() const +{ + double d = qt_inf(); + QVERIFY(qIsInf(d)); +} + +QTEST_MAIN(tst_Compiler) +#include "tst_compiler.moc" |