File: indexedducontext.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 (131 lines) | stat: -rw-r--r-- 3,217 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
/*
    SPDX-FileCopyrightText: 2006 Hamish Rodda <rodda@kde.org>
    SPDX-FileCopyrightText: 2007-2009 David Nolden <david.nolden.kdevelop@art-master.de>

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

#ifndef KDEVPLATFORM_INDEXEDDUCONTEXT_H
#define KDEVPLATFORM_INDEXEDDUCONTEXT_H

#include <language/languageexport.h>
#include <language/util/kdevhash.h>

#include <QPair>

namespace KDevelop {
class DUContext;
class IndexedTopDUContext;

/**
 * Represents a context only by its global indices
 */
class KDEVPLATFORMLANGUAGE_EXPORT IndexedDUContext
{
public:
    IndexedDUContext(DUContext* decl);
    IndexedDUContext(uint topContext = 0, uint contextIndex = 0);

    ///Duchain must be read locked
    DUContext* context() const;

    ///Duchain must be read locked
    DUContext* data() const
    {
        return context();
    }

    bool operator==(const IndexedDUContext& rhs) const
    {
        return m_topContext == rhs.m_topContext && m_contextIndex == rhs.m_contextIndex;
    }
    uint hash() const
    {
        return KDevHash() << m_topContext << m_contextIndex;
    }

    bool isValid() const
    {
        return !isDummy() && context() != nullptr;
    }

    bool operator<(const IndexedDUContext& rhs) const
    {
        Q_ASSERT(!isDummy());
        return m_topContext < rhs.m_topContext ||
               (m_topContext == rhs.m_topContext && m_contextIndex < rhs.m_contextIndex);
    }

    //Index within the top-context
    uint localIndex() const
    {
        if (isDummy())
            return 0;

        return m_contextIndex;
    }

    uint topContextIndex() const
    {
        return m_topContext;
    }

    IndexedTopDUContext indexedTopContext() const;

    /**
     * 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 = 1 << 31;
        else
            m_topContext = 0;
        m_contextIndex = 0;
    }

    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 & (1 << 31));
    }

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

    ///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_contextIndex = data.second;
        Q_ASSERT(!isDummy());
        m_topContext |= (1 << 31); //Mark as dummy
        Q_ASSERT(isDummy());
        Q_ASSERT(dummyData() == data);
    }

private:
    uint m_topContext;
    uint m_contextIndex;
};

inline uint qHash(const IndexedDUContext& ctx)
{
    return ctx.hash();
}
}

Q_DECLARE_TYPEINFO(KDevelop::IndexedDUContext, Q_MOVABLE_TYPE);

#endif // KDEVPLATFORM_INDEXEDDUCONTEXT_H