1 /*
2     SPDX-FileCopyrightText: 2006 Roberto Raggi <roberto@kdevelop.org>
3     SPDX-FileCopyrightText: 2006-2008 Hamish Rodda <rodda@kde.org>
4     SPDX-FileCopyrightText: 2007-2008 David Nolden <david.nolden.kdevelop@art-master.de>
5 
6     SPDX-License-Identifier: LGPL-2.0-only
7 */
8 
9 #include "abstracttype.h"
10 
11 #include "typesystemdata.h"
12 #include "typeregister.h"
13 #include "typesystem.h"
14 #include "typerepository.h"
15 #include <debug.h>
16 
17 namespace KDevelop {
18 //REGISTER_TYPE(AbstractType);
19 
makeDynamic()20 void AbstractType::makeDynamic()
21 {
22     if (d_ptr->m_dynamic)
23         return;
24     AbstractType::Ptr newType(clone()); //While cloning, all the data is cloned as well. So we use that mechanism and steal the cloned data.
25     Q_ASSERT(newType->equals(this));
26     AbstractTypeData* oldData = d_ptr;
27     d_ptr = newType->d_ptr;
28     newType->d_ptr = oldData;
29     Q_ASSERT(d_ptr->m_dynamic);
30 }
31 
AbstractType(AbstractTypeData & dd)32 AbstractType::AbstractType(AbstractTypeData& dd)
33     : d_ptr(&dd)
34 {
35 }
36 
modifiers() const37 quint32 AbstractType::modifiers() const
38 {
39     return d_func()->m_modifiers;
40 }
41 
setModifiers(quint32 modifiers)42 void AbstractType::setModifiers(quint32 modifiers)
43 {
44     d_func_dynamic()->m_modifiers = modifiers;
45 }
46 
sizeOf() const47 int64_t AbstractType::sizeOf() const
48 {
49     return d_func()->m_sizeOf;
50 }
51 
setSizeOf(int64_t sizeOf)52 void AbstractType::setSizeOf(int64_t sizeOf)
53 {
54     d_func_dynamic()->m_sizeOf = sizeOf;
55 }
56 
alignOf() const57 int64_t AbstractType::alignOf() const
58 {
59     if (d_func()->m_alignOfExponent == AbstractTypeData::MaxAlignOfExponent) {
60         return -1;
61     } else {
62         return Q_INT64_C(1) << d_func()->m_alignOfExponent;
63     }
64 }
65 
setAlignOf(int64_t alignedTo)66 void AbstractType::setAlignOf(int64_t alignedTo)
67 {
68     if (alignedTo <= 0) {
69         d_func_dynamic()->m_alignOfExponent = AbstractTypeData::MaxAlignOfExponent;
70         return;
71     }
72 
73     unsigned int alignOfExponent = 0;
74     while (alignedTo >>= 1)
75         alignOfExponent++;
76     d_func_dynamic()->m_alignOfExponent = alignOfExponent;
77 }
78 
AbstractType()79 AbstractType::AbstractType()
80     : d_ptr(&createData<AbstractType>())
81 {
82 }
83 
~AbstractType()84 AbstractType::~AbstractType()
85 {
86     if (!d_ptr->inRepository) {
87         TypeSystem::self().callDestructor(d_ptr);
88         delete[] ( char* )d_ptr;
89     }
90 }
91 
accept(TypeVisitor * v) const92 void AbstractType::accept(TypeVisitor* v) const
93 {
94     if (v->preVisit(this))
95         this->accept0(v);
96 
97     v->postVisit(this);
98 }
99 
acceptType(AbstractType::Ptr type,TypeVisitor * v)100 void AbstractType::acceptType(AbstractType::Ptr type, TypeVisitor* v)
101 {
102     if (!type)
103         return;
104 
105     type->accept(v);
106 }
107 
whichType() const108 AbstractType::WhichType AbstractType::whichType() const
109 {
110     return TypeAbstract;
111 }
112 
exchangeTypes(TypeExchanger *)113 void AbstractType::exchangeTypes(TypeExchanger* /*exchanger */)
114 {
115 }
116 
indexed() const117 IndexedType AbstractType::indexed() const
118 {
119     return IndexedType(AbstractType::Ptr(const_cast<AbstractType*>(this)));
120 }
121 
equals(const AbstractType * rhs) const122 bool AbstractType::equals(const AbstractType* rhs) const
123 {
124     //qCDebug(LANGUAGE) << this << rhs << modifiers() << rhs->modifiers();
125     return d_func()->typeClassId == rhs->d_func()->typeClassId && d_func()->m_modifiers == rhs->d_func()->m_modifiers
126         && d_func()->m_sizeOf == rhs->d_func()->m_sizeOf
127         && d_func()->m_alignOfExponent == rhs->d_func()->m_alignOfExponent;
128 }
129 
hash() const130 uint AbstractType::hash() const
131 {
132     return KDevHash() << d_func()->typeClassId << d_func()->m_modifiers << d_func()->m_sizeOf
133                       << d_func()->m_alignOfExponent;
134 }
135 
toString() const136 QString AbstractType::toString() const
137 {
138     return toString(false);
139 }
140 
toString(bool spaceOnLeft) const141 QString AbstractType::toString(bool spaceOnLeft) const
142 {
143     // TODO complete
144     if (!spaceOnLeft) {
145         if (modifiers() & ConstModifier) {
146             if (modifiers() & VolatileModifier) {
147                 return QStringLiteral("const volatile ");
148             } else {
149                 return QStringLiteral("const ");
150             }
151         } else {
152             if (modifiers() & VolatileModifier)
153                 return QStringLiteral("volatile ");
154             else
155                 return QString();
156         }
157     } else {
158         if (modifiers() & ConstModifier) {
159             if (modifiers() & VolatileModifier) {
160                 return QStringLiteral(" const volatile");
161             } else {
162                 return QStringLiteral(" const");
163             }
164         } else {
165             if (modifiers() & VolatileModifier)
166                 return QStringLiteral(" volatile");
167             else
168                 return QString();
169         }
170     }
171 }
172 }
173