1 /* 2 SPDX-FileCopyrightText: 2007 David Nolden <david.nolden.kdevelop@art-master.de> 3 SPDX-FileCopyrightText: 2014 Sven Brauch <svenbrauch@gmail.com> 4 5 SPDX-License-Identifier: LGPL-2.0-only 6 */ 7 8 #include "typeutils.h" 9 #include "referencetype.h" 10 #include "pointertype.h" 11 #include "typealiastype.h" 12 #include "unsuretype.h" 13 #include "integraltype.h" 14 15 namespace TypeUtils { 16 using namespace KDevelop; 17 unAliasedType(const TypePtr<KDevelop::AbstractType> & _type)18TypePtr<KDevelop::AbstractType> unAliasedType(const TypePtr<KDevelop::AbstractType>& _type) 19 { 20 TypePtr<KDevelop::AbstractType> type = _type; 21 22 TypePtr<KDevelop::TypeAliasType> alias = type.cast<KDevelop::TypeAliasType>(); 23 24 int depth = 0; //Prevent endless recursion 25 while (alias && depth < 20) { 26 uint hadModifiers = alias->modifiers(); 27 28 type = alias->type(); 29 30 if (hadModifiers && type) 31 type->setModifiers(type->modifiers() | hadModifiers); 32 33 alias = type.cast<KDevelop::TypeAliasType>(); 34 ++depth; 35 } 36 37 return type; 38 } 39 40 ///@todo remove constant and topContext targetType(const AbstractType::Ptr & _base,const TopDUContext *,bool *)41AbstractType::Ptr targetType(const AbstractType::Ptr& _base, const TopDUContext* /*topContext*/, bool* /*constant*/) 42 { 43 AbstractType::Ptr base(_base); 44 45 ReferenceType::Ptr ref = base.cast<ReferenceType>(); 46 PointerType::Ptr pnt = base.cast<PointerType>(); 47 TypeAliasType::Ptr alias = base.cast<TypeAliasType>(); 48 49 while (ref || pnt || alias) { 50 uint hadModifiers = base->modifiers(); 51 52 if (ref) { 53 base = ref->baseType(); 54 } else if (pnt) { 55 base = pnt->baseType(); 56 } else { 57 base = alias->type(); 58 } 59 if ((alias || ref) && hadModifiers && base) 60 base->setModifiers(base->modifiers() | hadModifiers); 61 62 ref = base.cast<ReferenceType>(); 63 pnt = base.cast<PointerType>(); 64 alias = base.cast<TypeAliasType>(); 65 } 66 67 return base; 68 } 69 targetTypeKeepAliases(const AbstractType::Ptr & _base,const TopDUContext *,bool *)70AbstractType::Ptr targetTypeKeepAliases(const AbstractType::Ptr& _base, const TopDUContext* /*topContext*/, 71 bool* /*constant*/) 72 { 73 AbstractType::Ptr base(_base); 74 75 ReferenceType::Ptr ref = base.cast<ReferenceType>(); 76 PointerType::Ptr pnt = base.cast<PointerType>(); 77 78 while (ref || pnt) { 79 if (ref) { 80 uint hadModifiers = ref->modifiers(); 81 base = ref->baseType(); 82 if (hadModifiers && base) 83 base->setModifiers(base->modifiers() | hadModifiers); 84 } else if (pnt) { 85 base = pnt->baseType(); 86 } 87 ref = base.cast<ReferenceType>(); 88 pnt = base.cast<PointerType>(); 89 } 90 91 return base; 92 } 93 resolveAliasType(const AbstractType::Ptr & eventualAlias)94AbstractType::Ptr resolveAliasType(const AbstractType::Ptr& eventualAlias) 95 { 96 if (eventualAlias && eventualAlias->whichType() == KDevelop::AbstractType::TypeAlias) { 97 return eventualAlias.cast<TypeAliasType>()->type(); 98 } 99 return eventualAlias; 100 } 101 isUsefulType(AbstractType::Ptr type)102bool isUsefulType(AbstractType::Ptr type) 103 { 104 type = resolveAliasType(type); 105 if (!type) { 106 return false; 107 } 108 if (type->whichType() != AbstractType::TypeIntegral) { 109 return true; 110 } 111 auto dtype = type.cast<IntegralType>()->dataType(); 112 if (dtype != IntegralType::TypeMixed && dtype != IntegralType::TypeNull) { 113 return true; 114 } 115 return false; 116 } 117 } // namespace TypeUtils 118