File: indexeddeclaration.h

package info (click to toggle)
kdevelop 4%3A22.12.2-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 70,096 kB
  • sloc: cpp: 284,635; javascript: 3,558; python: 3,422; sh: 1,319; ansic: 685; xml: 331; php: 95; lisp: 66; makefile: 39; sed: 12
file content (156 lines) | stat: -rw-r--r-- 3,943 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/*
    SPDX-FileCopyrightText: 2007 David Nolden <david.nolden.kdevelop@art-master.de>

    SPDX-License-Identifier: LGPL-2.0-only
*/

#ifndef KDEVPLATFORM_INDEXEDDECLARATION_H
#define KDEVPLATFORM_INDEXEDDECLARATION_H

#include <language/languageexport.h>

#include "indexedtopducontext.h"
#include <language/util/kdevhash.h>

namespace KDevelop {
class Declaration;

/**
 * Represents a declaration only by its global indices
 */
class KDEVPLATFORMLANGUAGE_EXPORT IndexedDeclaration
{
public:
    IndexedDeclaration(const Declaration* decl = nullptr);
    IndexedDeclaration(uint topContext, uint declarationIndex);

    /**
     * \warning Duchain must be read locked
     */
    Declaration* declaration() const;

    /**
     * \warning Duchain must be read locked
     */
    Declaration* data() const
    {
        return declaration();
    }

    inline bool operator==(const IndexedDeclaration& rhs) const
    {
        return m_topContext == rhs.m_topContext && m_declarationIndex == rhs.m_declarationIndex;
    }

    inline bool operator!=(const IndexedDeclaration& rhs) const { return !operator==(rhs); }

    inline uint hash() const
    {
        if (isDummy())
            return 0;
        return KDevHash() << m_topContext << m_declarationIndex;
    }

    ///@warning The duchain needs to be locked when this is called
    inline bool isValid() const
    {
        return !isDummy() && declaration() != nullptr;
    }

    inline bool operator<(const IndexedDeclaration& rhs) const
    {
        Q_ASSERT(!isDummy());
        return m_topContext < rhs.m_topContext ||
               (m_topContext == rhs.m_topContext && m_declarationIndex < rhs.m_declarationIndex);
    }

    /**
     * \return Index of the Declaration within the top context
     */
    inline uint localIndex() const
    {
        if (isDummy())
            return 0;
        else
            return m_declarationIndex;
    }

    inline uint topContextIndex() const
    {
        if (isDummy())
            return 0;
        else
            return m_topContext;
    }

    inline IndexedTopDUContext indexedTopContext() const
    {
        if (isDummy())
            return IndexedTopDUContext();
        else
            return IndexedTopDUContext(m_topContext);
    }

    /**
     * The following functions allow storing 2 integers in this object and marking it as a dummy,
     * which makes the isValid() function always return false for this object, and use the integers
     * for other purposes.
     *
     * Clears the contained data
     */
    void setIsDummy(bool dummy)
    {
        if (isDummy() == dummy)
            return;
        if (dummy)
            m_topContext = 1u << 31u;
        else
            m_topContext = 0;
        m_declarationIndex = 0;
    }

    inline bool isDummy() const
    {
        //We use the second highest bit to mark dummies, because the highest is used for the sign bit of stored
        //integers
        return ( bool )(m_topContext & static_cast<uint>(1u << 31u));
    }

    inline QPair<uint, uint> dummyData() const
    {
        Q_ASSERT(isDummy());
        return qMakePair(m_topContext & (~(1u << 31u)), m_declarationIndex);
    }

    /**
     * \warning Do not call this when this object is valid.
     *
     * The first integer loses one bit of precision.
     */
    void setDummyData(QPair<uint, uint> data)
    {
        Q_ASSERT(isDummy());

        m_topContext = data.first;
        m_declarationIndex = data.second;
        Q_ASSERT(!isDummy());
        m_topContext |= (1u << 31u); //Mark as dummy
        Q_ASSERT(isDummy());
        Q_ASSERT(dummyData() == data);
    }

private:
    uint m_topContext;
    uint m_declarationIndex;
};

inline uint qHash(const IndexedDeclaration& decl)
{
    return decl.hash();
}
}

Q_DECLARE_METATYPE(KDevelop::IndexedDeclaration)
Q_DECLARE_TYPEINFO(KDevelop::IndexedDeclaration, Q_MOVABLE_TYPE);

#endif // KDEVPLATFORM_INDEXEDDECLARATION_H