Changeset View
Changeset View
Standalone View
Standalone View
language/duchain/declarationid.cpp
Show All 27 Lines | |||||
28 | #include "../editor/cursorinrevision.h" | 28 | #include "../editor/cursorinrevision.h" | ||
29 | 29 | | |||
30 | #include <util/convenientfreelist.h> | 30 | #include <util/convenientfreelist.h> | ||
31 | 31 | | |||
32 | namespace KDevelop { | 32 | namespace KDevelop { | ||
33 | 33 | | |||
34 | DeclarationId::DeclarationId(const IndexedQualifiedIdentifier& id, uint additionalId, | 34 | DeclarationId::DeclarationId(const IndexedQualifiedIdentifier& id, uint additionalId, | ||
35 | const IndexedInstantiationInformation& specialization) | 35 | const IndexedInstantiationInformation& specialization) | ||
36 | : m_direct(false) | 36 | : m_indirectData{id, additionalId} | ||
37 | , m_isDirect(false) | ||||
37 | , m_specialization(specialization) | 38 | , m_specialization(specialization) | ||
38 | { | 39 | { | ||
39 | indirect.m_identifier = id; | | |||
40 | indirect.m_additionalIdentity = additionalId; | | |||
41 | } | 40 | } | ||
42 | 41 | | |||
43 | DeclarationId::DeclarationId(const IndexedDeclaration& decl, | 42 | DeclarationId::DeclarationId(const IndexedDeclaration& decl, | ||
44 | const IndexedInstantiationInformation& specialization) | 43 | const IndexedInstantiationInformation& specialization) | ||
45 | : direct(decl) | 44 | : m_directData(decl) | ||
46 | , m_direct(true) | 45 | , m_isDirect(true) | ||
47 | , m_specialization(specialization) | 46 | , m_specialization(specialization) | ||
48 | { | 47 | { | ||
48 | } | ||||
49 | 49 | | |||
50 | DeclarationId::DeclarationId(const DeclarationId& rhs) | ||||
51 | : m_isDirect(rhs.m_isDirect) | ||||
52 | , m_specialization(rhs.m_specialization) | ||||
53 | { | ||||
54 | if (m_isDirect) { | ||||
55 | m_directData = rhs.m_directData; | ||||
56 | } else { | ||||
57 | // IndexedQualifiedIdentifier doesn't like zero-initialization... | ||||
58 | new (&m_indirectData.identifier) IndexedQualifiedIdentifier(rhs.m_indirectData.identifier); | ||||
59 | m_indirectData.additionalIdentity = rhs.m_indirectData.additionalIdentity; | ||||
60 | } | ||||
61 | } | ||||
62 | | ||||
63 | DeclarationId::~DeclarationId() | ||||
64 | { | ||||
mwolff: you'll also need to call the correct destructors here, afaik. otherwise we could leak the… | |||||
65 | } | ||||
66 | | ||||
67 | DeclarationId& DeclarationId::operator=(const DeclarationId& rhs) | ||||
68 | { | ||||
69 | if (&rhs == this) | ||||
70 | return *this; | ||||
71 | | ||||
72 | m_isDirect = rhs.m_isDirect; | ||||
73 | m_specialization = rhs.m_specialization; | ||||
74 | if (m_isDirect) { | ||||
75 | m_directData = rhs.m_directData; | ||||
76 | } else { | ||||
77 | m_indirectData = rhs.m_indirectData; | ||||
78 | } | ||||
79 | return *this; | ||||
50 | } | 80 | } | ||
51 | 81 | | |||
52 | bool DeclarationId::isDirect() const | 82 | bool DeclarationId::isDirect() const | ||
53 | { | 83 | { | ||
54 | return m_direct; | 84 | return m_isDirect; | ||
55 | } | 85 | } | ||
56 | 86 | | |||
57 | void DeclarationId::setSpecialization(const IndexedInstantiationInformation& spec) | 87 | void DeclarationId::setSpecialization(const IndexedInstantiationInformation& spec) | ||
58 | { | 88 | { | ||
59 | m_specialization = spec; | 89 | m_specialization = spec; | ||
60 | } | 90 | } | ||
61 | 91 | | |||
62 | IndexedInstantiationInformation DeclarationId::specialization() const | 92 | IndexedInstantiationInformation DeclarationId::specialization() const | ||
63 | { | 93 | { | ||
64 | return m_specialization; | 94 | return m_specialization; | ||
65 | } | 95 | } | ||
66 | 96 | | |||
67 | KDevVarLengthArray<Declaration*> DeclarationId::getDeclarations(const TopDUContext* top) const | 97 | KDevVarLengthArray<Declaration*> DeclarationId::getDeclarations(const TopDUContext* top) const | ||
68 | { | 98 | { | ||
69 | KDevVarLengthArray<Declaration*> ret; | 99 | KDevVarLengthArray<Declaration*> ret; | ||
70 | 100 | | |||
71 | if(m_direct == false) { | 101 | if(m_isDirect == false) { | ||
72 | //Find the declaration by its qualified identifier and additionalIdentity | 102 | //Find the declaration by its qualified identifier and additionalIdentity | ||
73 | QualifiedIdentifier id(indirect.m_identifier); | 103 | QualifiedIdentifier id(m_indirectData.identifier); | ||
74 | 104 | | |||
75 | if(top) { | 105 | if(top) { | ||
76 | //Do filtering | 106 | //Do filtering | ||
77 | PersistentSymbolTable::FilteredDeclarationIterator filter = | 107 | PersistentSymbolTable::FilteredDeclarationIterator filter = | ||
78 | PersistentSymbolTable::self().getFilteredDeclarations(id, top->recursiveImportIndices()); | 108 | PersistentSymbolTable::self().getFilteredDeclarations(id, top->recursiveImportIndices()); | ||
79 | for(; filter; ++filter) { | 109 | for(; filter; ++filter) { | ||
80 | Declaration* decl = filter->data(); | 110 | Declaration* decl = filter->data(); | ||
81 | if(decl && indirect.m_additionalIdentity == decl->additionalIdentity()) { | 111 | if(decl && m_indirectData.additionalIdentity == decl->additionalIdentity()) { | ||
82 | //Hit | 112 | //Hit | ||
83 | ret.append(decl); | 113 | ret.append(decl); | ||
84 | } | 114 | } | ||
85 | } | 115 | } | ||
86 | }else{ | 116 | }else{ | ||
87 | //Just accept anything | 117 | //Just accept anything | ||
88 | PersistentSymbolTable::Declarations decls = PersistentSymbolTable::self().getDeclarations(id); | 118 | PersistentSymbolTable::Declarations decls = PersistentSymbolTable::self().getDeclarations(id); | ||
89 | PersistentSymbolTable::Declarations::Iterator decl = decls.iterator(); | 119 | PersistentSymbolTable::Declarations::Iterator decl = decls.iterator(); | ||
90 | for(; decl; ++decl) { | 120 | for(; decl; ++decl) { | ||
91 | const IndexedDeclaration& iDecl(*decl); | 121 | const IndexedDeclaration& iDecl(*decl); | ||
92 | 122 | | |||
93 | ///@todo think this over once we don't pull in all imported top-context any more | 123 | ///@todo think this over once we don't pull in all imported top-context any more | ||
94 | //Don't trigger loading of top-contexts from here, it will create a lot of problems | 124 | //Don't trigger loading of top-contexts from here, it will create a lot of problems | ||
95 | if((!DUChain::self()->isInMemory(iDecl.topContextIndex()))) | 125 | if((!DUChain::self()->isInMemory(iDecl.topContextIndex()))) | ||
96 | continue; | 126 | continue; | ||
97 | 127 | | |||
98 | if(!top) { | 128 | if(!top) { | ||
99 | Declaration* decl = iDecl.data(); | 129 | Declaration* decl = iDecl.data(); | ||
100 | if(decl && indirect.m_additionalIdentity == decl->additionalIdentity()) { | 130 | if(decl && m_indirectData.additionalIdentity == decl->additionalIdentity()) { | ||
101 | //Hit | 131 | //Hit | ||
102 | ret.append(decl); | 132 | ret.append(decl); | ||
103 | } | 133 | } | ||
104 | } | 134 | } | ||
105 | } | 135 | } | ||
106 | } | 136 | } | ||
107 | }else{ | 137 | }else{ | ||
108 | Declaration* decl = direct.declaration(); | 138 | Declaration* decl = m_directData.declaration(); | ||
109 | if(decl) | 139 | if(decl) | ||
110 | ret.append(decl); | 140 | ret.append(decl); | ||
111 | } | 141 | } | ||
112 | 142 | | |||
113 | if(!ret.isEmpty() && m_specialization.index()) { | 143 | if(!ret.isEmpty() && m_specialization.index()) { | ||
114 | KDevVarLengthArray<Declaration*> newRet; | 144 | KDevVarLengthArray<Declaration*> newRet; | ||
115 | for (Declaration* decl : ret) { | 145 | for (Declaration* decl : ret) { | ||
116 | Declaration* specialized = decl->specialize(m_specialization, top ? top : decl->topContext()); | 146 | Declaration* specialized = decl->specialize(m_specialization, top ? top : decl->topContext()); | ||
117 | if(specialized) | 147 | if(specialized) | ||
118 | newRet.append(specialized); | 148 | newRet.append(specialized); | ||
119 | } | 149 | } | ||
120 | return newRet; | 150 | return newRet; | ||
121 | } | 151 | } | ||
122 | return ret; | 152 | return ret; | ||
123 | } | 153 | } | ||
124 | 154 | | |||
125 | Declaration* DeclarationId::getDeclaration(const TopDUContext* top, bool instantiateIfRequired) const | 155 | Declaration* DeclarationId::getDeclaration(const TopDUContext* top, bool instantiateIfRequired) const | ||
126 | { | 156 | { | ||
127 | Declaration* ret = 0; | 157 | Declaration* ret = 0; | ||
128 | 158 | | |||
129 | if(m_direct == false) { | 159 | if(m_isDirect == false) { | ||
130 | //Find the declaration by its qualified identifier and additionalIdentity | 160 | //Find the declaration by its qualified identifier and additionalIdentity | ||
131 | QualifiedIdentifier id(indirect.m_identifier); | 161 | QualifiedIdentifier id(m_indirectData.identifier); | ||
132 | 162 | | |||
133 | if(top) { | 163 | if(top) { | ||
134 | //Do filtering | 164 | //Do filtering | ||
135 | PersistentSymbolTable::FilteredDeclarationIterator filter = | 165 | PersistentSymbolTable::FilteredDeclarationIterator filter = | ||
136 | PersistentSymbolTable::self().getFilteredDeclarations(id, top->recursiveImportIndices()); | 166 | PersistentSymbolTable::self().getFilteredDeclarations(id, top->recursiveImportIndices()); | ||
137 | for(; filter; ++filter) { | 167 | for(; filter; ++filter) { | ||
138 | Declaration* decl = filter->data(); | 168 | Declaration* decl = filter->data(); | ||
139 | if(decl && indirect.m_additionalIdentity == decl->additionalIdentity()) { | 169 | if(decl && m_indirectData.additionalIdentity == decl->additionalIdentity()) { | ||
140 | //Hit | 170 | //Hit | ||
141 | ret = decl; | 171 | ret = decl; | ||
142 | if(!ret->isForwardDeclaration()) | 172 | if(!ret->isForwardDeclaration()) | ||
143 | break; | 173 | break; | ||
144 | } | 174 | } | ||
145 | } | 175 | } | ||
146 | }else{ | 176 | }else{ | ||
147 | //Just accept anything | 177 | //Just accept anything | ||
148 | PersistentSymbolTable::Declarations decls = PersistentSymbolTable::self().getDeclarations(id); | 178 | PersistentSymbolTable::Declarations decls = PersistentSymbolTable::self().getDeclarations(id); | ||
149 | PersistentSymbolTable::Declarations::Iterator decl = decls.iterator(); | 179 | PersistentSymbolTable::Declarations::Iterator decl = decls.iterator(); | ||
150 | for(; decl; ++decl) { | 180 | for(; decl; ++decl) { | ||
151 | const IndexedDeclaration& iDecl(*decl); | 181 | const IndexedDeclaration& iDecl(*decl); | ||
152 | 182 | | |||
153 | ///@todo think this over once we don't pull in all imported top-context any more | 183 | ///@todo think this over once we don't pull in all imported top-context any more | ||
154 | //Don't trigger loading of top-contexts from here, it will create a lot of problems | 184 | //Don't trigger loading of top-contexts from here, it will create a lot of problems | ||
155 | if((!DUChain::self()->isInMemory(iDecl.topContextIndex()))) | 185 | if((!DUChain::self()->isInMemory(iDecl.topContextIndex()))) | ||
156 | continue; | 186 | continue; | ||
157 | 187 | | |||
158 | if(!top) { | 188 | if(!top) { | ||
159 | Declaration* decl = iDecl.data(); | 189 | Declaration* decl = iDecl.data(); | ||
160 | if(decl && indirect.m_additionalIdentity == decl->additionalIdentity()) { | 190 | if(decl && m_indirectData.additionalIdentity == decl->additionalIdentity()) { | ||
161 | //Hit | 191 | //Hit | ||
162 | ret = decl; | 192 | ret = decl; | ||
163 | if(!ret->isForwardDeclaration()) | 193 | if(!ret->isForwardDeclaration()) | ||
164 | break; | 194 | break; | ||
165 | } | 195 | } | ||
166 | } | 196 | } | ||
167 | } | 197 | } | ||
168 | } | 198 | } | ||
169 | }else{ | 199 | }else{ | ||
170 | //Find the declaration by m_topContext and m_declaration | 200 | //Find the declaration by m_topContext and m_declaration | ||
171 | ret = direct.declaration(); | 201 | ret = m_directData.declaration(); | ||
172 | } | 202 | } | ||
173 | 203 | | |||
174 | 204 | | |||
175 | if(ret) | 205 | if(ret) | ||
176 | { | 206 | { | ||
177 | if(m_specialization.isValid()) | 207 | if(m_specialization.isValid()) | ||
178 | { | 208 | { | ||
179 | const TopDUContext* topContextForSpecialization = top; | 209 | const TopDUContext* topContextForSpecialization = top; | ||
180 | if(!instantiateIfRequired) | 210 | if(!instantiateIfRequired) | ||
181 | topContextForSpecialization = 0; //If we don't want to instantiate new declarations, set the top-context to zero, so specialize(..) will only look-up | 211 | topContextForSpecialization = 0; //If we don't want to instantiate new declarations, set the top-context to zero, so specialize(..) will only look-up | ||
182 | else if(!topContextForSpecialization) | 212 | else if(!topContextForSpecialization) | ||
183 | topContextForSpecialization = ret->topContext(); | 213 | topContextForSpecialization = ret->topContext(); | ||
184 | 214 | | |||
185 | return ret->specialize(m_specialization, topContextForSpecialization); | 215 | return ret->specialize(m_specialization, topContextForSpecialization); | ||
186 | }else{ | 216 | }else{ | ||
187 | return ret; | 217 | return ret; | ||
188 | } | 218 | } | ||
189 | }else | 219 | }else | ||
190 | return 0; | 220 | return 0; | ||
191 | } | 221 | } | ||
192 | 222 | | |||
193 | QualifiedIdentifier DeclarationId::qualifiedIdentifier() const | 223 | QualifiedIdentifier DeclarationId::qualifiedIdentifier() const | ||
194 | { | 224 | { | ||
195 | 225 | | |||
196 | if(!m_direct) { | 226 | if(!m_isDirect) { | ||
197 | QualifiedIdentifier baseIdentifier = indirect.m_identifier.identifier(); | 227 | QualifiedIdentifier baseIdentifier = m_indirectData.identifier.identifier(); | ||
198 | if(!m_specialization.index()) | 228 | if(!m_specialization.index()) | ||
199 | return baseIdentifier; | 229 | return baseIdentifier; | ||
200 | return m_specialization.information().applyToIdentifier(baseIdentifier); | 230 | return m_specialization.information().applyToIdentifier(baseIdentifier); | ||
201 | } else { | 231 | } else { | ||
202 | Declaration* decl = getDeclaration(0); | 232 | Declaration* decl = getDeclaration(0); | ||
203 | if(decl) | 233 | if(decl) | ||
204 | return decl->qualifiedIdentifier(); | 234 | return decl->qualifiedIdentifier(); | ||
205 | 235 | | |||
206 | return QualifiedIdentifier(i18n("(unknown direct declaration)")); | 236 | return QualifiedIdentifier(i18n("(unknown direct declaration)")); | ||
207 | } | 237 | } | ||
208 | 238 | | |||
209 | return QualifiedIdentifier(i18n("(missing)")) + indirect.m_identifier.identifier(); | 239 | return QualifiedIdentifier(i18n("(missing)")) + m_indirectData.identifier.identifier(); | ||
210 | } | 240 | } | ||
211 | 241 | | |||
212 | } | 242 | } |
you'll also need to call the correct destructors here, afaik. otherwise we could leak the refcount of the indexed* types.