File indexing completed on 2024-06-16 04:23:17
0001 /* 0002 SPDX-FileCopyrightText: 2007 David Nolden <david.nolden.kdevelop@art-master.de> 0003 SPDX-FileCopyrightText: 2014 Sven Brauch <svenbrauch@gmail.com> 0004 0005 SPDX-License-Identifier: LGPL-2.0-only 0006 */ 0007 0008 #include "typeutils.h" 0009 #include "referencetype.h" 0010 #include "pointertype.h" 0011 #include "typealiastype.h" 0012 #include "unsuretype.h" 0013 #include "integraltype.h" 0014 0015 namespace TypeUtils { 0016 using namespace KDevelop; 0017 0018 AbstractType::Ptr unAliasedType(const AbstractType::Ptr& _type) 0019 { 0020 auto type = _type; 0021 auto alias = type.dynamicCast<KDevelop::TypeAliasType>(); 0022 0023 int depth = 0; //Prevent endless recursion 0024 while (alias && depth < 20) { 0025 uint hadModifiers = alias->modifiers(); 0026 0027 type = alias->type(); 0028 0029 if (hadModifiers && type) 0030 type->setModifiers(type->modifiers() | hadModifiers); 0031 0032 alias = type.dynamicCast<KDevelop::TypeAliasType>(); 0033 ++depth; 0034 } 0035 0036 return type; 0037 } 0038 0039 ///@todo remove constant and topContext 0040 AbstractType::Ptr targetType(const AbstractType::Ptr& _base, const TopDUContext* /*topContext*/, bool* /*constant*/) 0041 { 0042 auto base = _base; 0043 0044 auto ref = base.dynamicCast<ReferenceType>(); 0045 auto pnt = base.dynamicCast<PointerType>(); 0046 auto alias = base.dynamicCast<TypeAliasType>(); 0047 0048 while (ref || pnt || alias) { 0049 uint hadModifiers = base->modifiers(); 0050 0051 if (ref) { 0052 base = ref->baseType(); 0053 } else if (pnt) { 0054 base = pnt->baseType(); 0055 } else { 0056 base = alias->type(); 0057 } 0058 if ((alias || ref) && hadModifiers && base) 0059 base->setModifiers(base->modifiers() | hadModifiers); 0060 0061 ref = base.dynamicCast<ReferenceType>(); 0062 pnt = base.dynamicCast<PointerType>(); 0063 alias = base.dynamicCast<TypeAliasType>(); 0064 } 0065 0066 return base; 0067 } 0068 0069 AbstractType::Ptr targetTypeKeepAliases(const AbstractType::Ptr& _base, const TopDUContext* /*topContext*/, 0070 bool* /*constant*/) 0071 { 0072 auto base = _base; 0073 0074 auto ref = base.dynamicCast<ReferenceType>(); 0075 auto pnt = base.dynamicCast<PointerType>(); 0076 0077 while (ref || pnt) { 0078 if (ref) { 0079 uint hadModifiers = ref->modifiers(); 0080 base = ref->baseType(); 0081 if (hadModifiers && base) 0082 base->setModifiers(base->modifiers() | hadModifiers); 0083 } else if (pnt) { 0084 base = pnt->baseType(); 0085 } 0086 ref = base.dynamicCast<ReferenceType>(); 0087 pnt = base.dynamicCast<PointerType>(); 0088 } 0089 0090 return base; 0091 } 0092 0093 AbstractType::Ptr resolveAliasType(const AbstractType::Ptr& eventualAlias) 0094 { 0095 if (eventualAlias && eventualAlias->whichType() == KDevelop::AbstractType::TypeAlias) { 0096 return eventualAlias.staticCast<TypeAliasType>()->type(); 0097 } 0098 return eventualAlias; 0099 } 0100 0101 bool isUsefulType(AbstractType::Ptr type) 0102 { 0103 type = resolveAliasType(type); 0104 if (!type) { 0105 return false; 0106 } 0107 if (type->whichType() != AbstractType::TypeIntegral) { 0108 return true; 0109 } 0110 auto dtype = type.staticCast<IntegralType>()->dataType(); 0111 if (dtype != IntegralType::TypeMixed && dtype != IntegralType::TypeNull) { 0112 return true; 0113 } 0114 return false; 0115 } 0116 } // namespace TypeUtils