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