File indexing completed on 2024-05-12 04:38:02
0001 /* 0002 SPDX-FileCopyrightText: 2007 David Nolden <david.nolden.kdevelop@art-master.de> 0003 0004 SPDX-License-Identifier: LGPL-2.0-only 0005 */ 0006 0007 #ifndef KDEVPLATFORM_INDEXEDDECLARATION_H 0008 #define KDEVPLATFORM_INDEXEDDECLARATION_H 0009 0010 #include <language/languageexport.h> 0011 0012 #include "indexedtopducontext.h" 0013 #include <language/util/kdevhash.h> 0014 0015 namespace KDevelop { 0016 class Declaration; 0017 0018 /** 0019 * Represents a declaration only by its global indices 0020 */ 0021 class KDEVPLATFORMLANGUAGE_EXPORT IndexedDeclaration 0022 { 0023 public: 0024 IndexedDeclaration(const Declaration* decl = nullptr); 0025 IndexedDeclaration(uint topContext, uint declarationIndex); 0026 0027 /** 0028 * \warning Duchain must be read locked 0029 */ 0030 Declaration* declaration() const; 0031 0032 /** 0033 * \warning Duchain must be read locked 0034 */ 0035 Declaration* data() const 0036 { 0037 return declaration(); 0038 } 0039 0040 inline bool operator==(const IndexedDeclaration& rhs) const 0041 { 0042 return m_topContext == rhs.m_topContext && m_declarationIndex == rhs.m_declarationIndex; 0043 } 0044 0045 inline bool operator!=(const IndexedDeclaration& rhs) const { return !operator==(rhs); } 0046 0047 inline uint hash() const 0048 { 0049 if (isDummy()) 0050 return 0; 0051 return KDevHash() << m_topContext << m_declarationIndex; 0052 } 0053 0054 ///@warning The duchain needs to be locked when this is called 0055 inline bool isValid() const 0056 { 0057 return !isDummy() && declaration() != nullptr; 0058 } 0059 0060 inline bool operator<(const IndexedDeclaration& rhs) const 0061 { 0062 Q_ASSERT(!isDummy()); 0063 return m_topContext < rhs.m_topContext || 0064 (m_topContext == rhs.m_topContext && m_declarationIndex < rhs.m_declarationIndex); 0065 } 0066 0067 /** 0068 * \return Index of the Declaration within the top context 0069 */ 0070 inline uint localIndex() const 0071 { 0072 if (isDummy()) 0073 return 0; 0074 else 0075 return m_declarationIndex; 0076 } 0077 0078 inline uint topContextIndex() const 0079 { 0080 if (isDummy()) 0081 return 0; 0082 else 0083 return m_topContext; 0084 } 0085 0086 inline IndexedTopDUContext indexedTopContext() const 0087 { 0088 if (isDummy()) 0089 return IndexedTopDUContext(); 0090 else 0091 return IndexedTopDUContext(m_topContext); 0092 } 0093 0094 /** 0095 * The following functions allow storing 2 integers in this object and marking it as a dummy, 0096 * which makes the isValid() function always return false for this object, and use the integers 0097 * for other purposes. 0098 * 0099 * Clears the contained data 0100 */ 0101 void setIsDummy(bool dummy) 0102 { 0103 if (isDummy() == dummy) 0104 return; 0105 if (dummy) 0106 m_topContext = 1u << 31u; 0107 else 0108 m_topContext = 0; 0109 m_declarationIndex = 0; 0110 } 0111 0112 inline bool isDummy() const 0113 { 0114 //We use the second highest bit to mark dummies, because the highest is used for the sign bit of stored 0115 //integers 0116 return ( bool )(m_topContext & static_cast<uint>(1u << 31u)); 0117 } 0118 0119 inline QPair<uint, uint> dummyData() const 0120 { 0121 Q_ASSERT(isDummy()); 0122 return qMakePair(m_topContext & (~(1u << 31u)), m_declarationIndex); 0123 } 0124 0125 /** 0126 * \warning Do not call this when this object is valid. 0127 * 0128 * The first integer loses one bit of precision. 0129 */ 0130 void setDummyData(QPair<uint, uint> data) 0131 { 0132 Q_ASSERT(isDummy()); 0133 0134 m_topContext = data.first; 0135 m_declarationIndex = data.second; 0136 Q_ASSERT(!isDummy()); 0137 m_topContext |= (1u << 31u); //Mark as dummy 0138 Q_ASSERT(isDummy()); 0139 Q_ASSERT(dummyData() == data); 0140 } 0141 0142 private: 0143 uint m_topContext; 0144 uint m_declarationIndex; 0145 }; 0146 0147 inline uint qHash(const IndexedDeclaration& decl) 0148 { 0149 return decl.hash(); 0150 } 0151 } 0152 0153 Q_DECLARE_METATYPE(KDevelop::IndexedDeclaration) 0154 Q_DECLARE_TYPEINFO(KDevelop::IndexedDeclaration, Q_MOVABLE_TYPE); 0155 0156 #endif // KDEVPLATFORM_INDEXEDDECLARATION_H