File indexing completed on 2024-06-16 04:23:16

0001 /*
0002     SPDX-FileCopyrightText: 2002-2005 Roberto Raggi <roberto@kdevelop.org>
0003     SPDX-FileCopyrightText: 2006 Adam Treat <treat@kde.org>
0004     SPDX-FileCopyrightText: 2006-2008 Hamish Rodda <rodda@kde.org>
0005     SPDX-FileCopyrightText: 2007-2008 David Nolden <david.nolden.kdevelop@art-master.de>
0006 
0007     SPDX-License-Identifier: LGPL-2.0-only
0008 */
0009 
0010 #include "constantintegraltype.h"
0011 
0012 #include <debug.h>
0013 #include "typesystemdata.h"
0014 #include "typeregister.h"
0015 
0016 namespace KDevelop {
0017 REGISTER_TYPE(ConstantIntegralType);
0018 
0019 ConstantIntegralType::ConstantIntegralType(const ConstantIntegralType& rhs)
0020     : IntegralType(copyData<ConstantIntegralType>(*rhs.d_func()))
0021 {
0022 }
0023 
0024 ConstantIntegralType::ConstantIntegralType(ConstantIntegralTypeData& data)
0025     : IntegralType(data)
0026 {
0027 }
0028 
0029 ConstantIntegralType::ConstantIntegralType(uint type)
0030     : IntegralType(createData<ConstantIntegralType>())
0031 {
0032     setDataType(type);
0033     setModifiers(ConstModifier);
0034 }
0035 
0036 qint64 ConstantIntegralType::plainValue() const
0037 {
0038     return d_func()->m_value;
0039 }
0040 
0041 AbstractType* ConstantIntegralType::clone() const
0042 {
0043     return new ConstantIntegralType(*this);
0044 }
0045 
0046 bool ConstantIntegralType::equals(const AbstractType* _rhs) const
0047 {
0048     if (this == _rhs)
0049         return true;
0050 
0051     if (!IntegralType::equals(_rhs))
0052         return false;
0053 
0054     Q_ASSERT(dynamic_cast<const ConstantIntegralType*>(_rhs));
0055     const auto* rhs = static_cast<const ConstantIntegralType*>(_rhs);
0056 
0057     return d_func()->m_value == rhs->d_func()->m_value;
0058 }
0059 
0060 QString ConstantIntegralType::toString() const
0061 {
0062     QString ret;
0063 
0064     switch (dataType()) {
0065     case TypeNone:
0066         ret = QStringLiteral("none");
0067         break;
0068     case TypeChar:
0069         ret = QStringLiteral("char");
0070         break;
0071     case TypeWchar_t:
0072         ret = QStringLiteral("wchar_t");
0073         break;
0074     case TypeChar16_t:
0075         ret = QStringLiteral("char16_t");
0076         break;
0077     case TypeChar32_t:
0078         ret = QStringLiteral("char32_t");
0079         break;
0080     case TypeBoolean:
0081         ret = d_func()->m_value ? QStringLiteral("true") : QStringLiteral("false");
0082         break;
0083     case TypeInt:
0084         ret = (modifiers() & UnsignedModifier) ? QStringLiteral("unsigned") : QStringLiteral("int");
0085         break;
0086     case TypeHalf:
0087         ret = QStringLiteral("half");
0088         break;
0089     case TypeFloat:
0090         ret = QStringLiteral("float");
0091         break;
0092     case TypeDouble:
0093         ret = QStringLiteral("double");
0094         break;
0095     case TypeVoid:
0096         ret = QStringLiteral("void");
0097         break;
0098     default:
0099         ret = QStringLiteral("<unknown_value>");
0100         break;
0101     }
0102 
0103     return ret;
0104 }
0105 
0106 QString ConstantIntegralType::valueAsString() const
0107 {
0108     switch (dataType()) {
0109     case TypeNone:
0110         return QStringLiteral("none");
0111     case TypeChar:
0112         return QString::number(( char )d_func()->m_value);
0113     case TypeWchar_t:
0114         return QString::number(( wchar_t )d_func()->m_value);
0115     case TypeChar16_t:
0116         return QString::number(( char16_t )d_func()->m_value);
0117     case TypeChar32_t:
0118         return QString::number(( char32_t )d_func()->m_value);
0119     case TypeBoolean:
0120         return d_func()->m_value ? QStringLiteral("true") : QStringLiteral("false");
0121     case TypeInt:
0122         return (modifiers() & UnsignedModifier) ?
0123                QString::number(( uint )d_func()->m_value) :
0124                QString::number(( int )d_func()->m_value);
0125     case TypeHalf:
0126     case TypeFloat:
0127         return QString::number(value<float>());
0128     case TypeDouble:
0129         return QString::number(value<double>());
0130     default:
0131         return QString();
0132     }
0133 }
0134 
0135 uint ConstantIntegralType::hash() const
0136 {
0137     return KDevHash(IntegralType::hash()) << d_func()->m_value;
0138 }
0139 
0140 template <>
0141 KDEVPLATFORMLANGUAGE_EXPORT
0142 void ConstantIntegralType::setValueInternal<qint64>(qint64 value)
0143 {
0144     if ((modifiers() & UnsignedModifier)) {
0145         qCWarning(LANGUAGE) << "setValue(signed) called on unsigned type";
0146     }
0147     d_func_dynamic()->m_value = value;
0148 }
0149 
0150 template <>
0151 KDEVPLATFORMLANGUAGE_EXPORT
0152 void ConstantIntegralType::setValueInternal<quint64>(quint64 value)
0153 {
0154     if (!(modifiers() & UnsignedModifier)) {
0155         qCWarning(LANGUAGE) << "setValue(unsigned) called on not unsigned type";
0156     }
0157     d_func_dynamic()->m_value = ( qint64 )value;
0158 }
0159 
0160 template <>
0161 KDEVPLATFORMLANGUAGE_EXPORT
0162 void ConstantIntegralType::setValueInternal<float>(float value)
0163 {
0164     if (dataType() != TypeFloat) {
0165         qCWarning(LANGUAGE) << "setValue(float) called on non-float type";
0166     }
0167     memcpy(&d_func_dynamic()->m_value, &value, sizeof(float));
0168 }
0169 
0170 template <>
0171 KDEVPLATFORMLANGUAGE_EXPORT
0172 void ConstantIntegralType::setValueInternal<double>(double value)
0173 {
0174     if (dataType() != TypeDouble) {
0175         qCWarning(LANGUAGE) << "setValue(double) called on non-double type";
0176     }
0177     memcpy(&d_func_dynamic()->m_value, &value, sizeof(double));
0178 }
0179 }