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

0001 /*
0002     SPDX-FileCopyrightText: 2006 Roberto Raggi <roberto@kdevelop.org>
0003     SPDX-FileCopyrightText: 2006-2008 Hamish Rodda <rodda@kde.org>
0004     SPDX-FileCopyrightText: 2007-2008 David Nolden <david.nolden.kdevelop@art-master.de>
0005 
0006     SPDX-License-Identifier: LGPL-2.0-only
0007 */
0008 
0009 #include "abstracttype.h"
0010 
0011 #include "typeregister.h"
0012 #include "typesystem.h"
0013 #include <debug.h>
0014 
0015 namespace KDevelop {
0016 //REGISTER_TYPE(AbstractType);
0017 
0018 void AbstractType::makeDynamic()
0019 {
0020     if (d_ptr->m_dynamic)
0021         return;
0022     AbstractType::Ptr newType(clone()); //While cloning, all the data is cloned as well. So we use that mechanism and steal the cloned data.
0023     Q_ASSERT(newType->equals(this));
0024     AbstractTypeData* oldData = d_ptr;
0025     d_ptr = newType->d_ptr;
0026     newType->d_ptr = oldData;
0027     Q_ASSERT(d_ptr->m_dynamic);
0028 }
0029 
0030 AbstractType::AbstractType(AbstractTypeData& dd)
0031     : d_ptr(&dd)
0032 {
0033 }
0034 
0035 quint32 AbstractType::modifiers() const
0036 {
0037     return d_func()->m_modifiers;
0038 }
0039 
0040 void AbstractType::setModifiers(quint32 modifiers)
0041 {
0042     d_func_dynamic()->m_modifiers = modifiers;
0043 }
0044 
0045 int64_t AbstractType::sizeOf() const
0046 {
0047     return d_func()->m_sizeOf;
0048 }
0049 
0050 void AbstractType::setSizeOf(int64_t sizeOf)
0051 {
0052     d_func_dynamic()->m_sizeOf = sizeOf;
0053 }
0054 
0055 int64_t AbstractType::alignOf() const
0056 {
0057     if (d_func()->m_alignOfExponent == AbstractTypeData::MaxAlignOfExponent) {
0058         return -1;
0059     } else {
0060         return Q_INT64_C(1) << d_func()->m_alignOfExponent;
0061     }
0062 }
0063 
0064 void AbstractType::setAlignOf(int64_t alignedTo)
0065 {
0066     if (alignedTo <= 0) {
0067         d_func_dynamic()->m_alignOfExponent = AbstractTypeData::MaxAlignOfExponent;
0068         return;
0069     }
0070 
0071     unsigned int alignOfExponent = 0;
0072     while (alignedTo >>= 1)
0073         alignOfExponent++;
0074     d_func_dynamic()->m_alignOfExponent = alignOfExponent;
0075 }
0076 
0077 AbstractType::AbstractType()
0078     : d_ptr(&createData<AbstractType>())
0079 {
0080 }
0081 
0082 AbstractType::~AbstractType()
0083 {
0084     if (!d_ptr->inRepository) {
0085         TypeSystem::self().callDestructor(d_ptr);
0086         delete[] ( char* )d_ptr;
0087     }
0088 }
0089 
0090 void AbstractType::accept(TypeVisitor* v) const
0091 {
0092     if (v->preVisit(this))
0093         this->accept0(v);
0094 
0095     v->postVisit(this);
0096 }
0097 
0098 void AbstractType::acceptType(AbstractType::Ptr type, TypeVisitor* v)
0099 {
0100     if (!type)
0101         return;
0102 
0103     type->accept(v);
0104 }
0105 
0106 AbstractType::WhichType AbstractType::whichType() const
0107 {
0108     return TypeAbstract;
0109 }
0110 
0111 void AbstractType::exchangeTypes(TypeExchanger* /*exchanger */)
0112 {
0113 }
0114 
0115 IndexedType AbstractType::indexed() const
0116 {
0117     return IndexedType(this);
0118 }
0119 
0120 bool AbstractType::equals(const AbstractType* rhs) const
0121 {
0122     //qCDebug(LANGUAGE) << this << rhs << modifiers() << rhs->modifiers();
0123     return d_func()->typeClassId == rhs->d_func()->typeClassId && d_func()->m_modifiers == rhs->d_func()->m_modifiers
0124         && d_func()->m_sizeOf == rhs->d_func()->m_sizeOf
0125         && d_func()->m_alignOfExponent == rhs->d_func()->m_alignOfExponent;
0126 }
0127 
0128 bool AbstractType::contains(const AbstractType* type) const
0129 {
0130     return equals(type);
0131 }
0132 
0133 uint AbstractType::hash() const
0134 {
0135     return KDevHash() << d_func()->typeClassId << d_func()->m_modifiers << d_func()->m_sizeOf
0136                       << d_func()->m_alignOfExponent;
0137 }
0138 
0139 QString AbstractType::toString() const
0140 {
0141     return toString(false);
0142 }
0143 
0144 QString AbstractType::toString(bool spaceOnLeft) const
0145 {
0146     // TODO complete
0147     QString modifiersStr;
0148 
0149     if (modifiers() & ConstModifier) {
0150         modifiersStr.append(QStringLiteral("const"));
0151     }
0152 
0153     if (modifiers() & VolatileModifier) {
0154         if (!modifiersStr.isEmpty())
0155             modifiersStr.append(QStringLiteral(" "));
0156         modifiersStr.append(QStringLiteral("volatile"));
0157     }
0158 
0159     if (modifiers() & AtomicModifier) {
0160         if (!modifiersStr.isEmpty())
0161             modifiersStr.append(QStringLiteral(" "));
0162         modifiersStr.append(QStringLiteral("_Atomic"));
0163     }
0164 
0165     if (!modifiersStr.isEmpty()) {
0166         if (spaceOnLeft)
0167             modifiersStr.prepend(QStringLiteral(" "));
0168         else
0169             modifiersStr.append(QStringLiteral(" "));
0170     }
0171 
0172     return modifiersStr;
0173 }
0174 }