File: | tools/lldb/source/Symbol/ClangASTImporter.cpp |
Location: | line 100, column 21 |
Description: | Function call argument is an uninitialized value |
1 | //===-- ClangASTImporter.cpp ------------------------------------*- C++ -*-===// | |||
2 | // | |||
3 | // The LLVM Compiler Infrastructure | |||
4 | // | |||
5 | // This file is distributed under the University of Illinois Open Source | |||
6 | // License. See LICENSE.TXT for details. | |||
7 | // | |||
8 | //===----------------------------------------------------------------------===// | |||
9 | ||||
10 | #include "clang/AST/Decl.h" | |||
11 | #include "clang/AST/DeclCXX.h" | |||
12 | #include "clang/AST/DeclObjC.h" | |||
13 | #include "llvm/Support/raw_ostream.h" | |||
14 | #include "lldb/Core/Log.h" | |||
15 | #include "lldb/Core/Module.h" | |||
16 | #include "lldb/Symbol/ClangASTContext.h" | |||
17 | #include "lldb/Symbol/ClangASTImporter.h" | |||
18 | #include "lldb/Symbol/ClangExternalASTSourceCommon.h" | |||
19 | #include "lldb/Symbol/ClangNamespaceDecl.h" | |||
20 | ||||
21 | using namespace lldb_private; | |||
22 | using namespace clang; | |||
23 | ||||
24 | ClangASTMetrics::Counters ClangASTMetrics::global_counters = { 0, 0, 0, 0, 0, 0 }; | |||
25 | ClangASTMetrics::Counters ClangASTMetrics::local_counters = { 0, 0, 0, 0, 0, 0 }; | |||
26 | ||||
27 | void ClangASTMetrics::DumpCounters (Log *log, ClangASTMetrics::Counters &counters) | |||
28 | { | |||
29 | log->Printf(" Number of visible Decl queries by name : %" PRIu64"l" "u", counters.m_visible_query_count); | |||
30 | log->Printf(" Number of lexical Decl queries : %" PRIu64"l" "u", counters.m_lexical_query_count); | |||
31 | log->Printf(" Number of imports initiated by LLDB : %" PRIu64"l" "u", counters.m_lldb_import_count); | |||
32 | log->Printf(" Number of imports conducted by Clang : %" PRIu64"l" "u", counters.m_clang_import_count); | |||
33 | log->Printf(" Number of Decls completed : %" PRIu64"l" "u", counters.m_decls_completed_count); | |||
34 | log->Printf(" Number of records laid out : %" PRIu64"l" "u", counters.m_record_layout_count); | |||
35 | } | |||
36 | ||||
37 | void ClangASTMetrics::DumpCounters (Log *log) | |||
38 | { | |||
39 | if (!log) | |||
40 | return; | |||
41 | ||||
42 | log->Printf("== ClangASTMetrics output =="); | |||
43 | log->Printf("-- Global metrics --"); | |||
44 | DumpCounters (log, global_counters); | |||
45 | log->Printf("-- Local metrics --"); | |||
46 | DumpCounters (log, local_counters); | |||
47 | } | |||
48 | ||||
49 | clang::QualType | |||
50 | ClangASTImporter::CopyType (clang::ASTContext *dst_ast, | |||
51 | clang::ASTContext *src_ast, | |||
52 | clang::QualType type) | |||
53 | { | |||
54 | MinionSP minion_sp (GetMinion(dst_ast, src_ast)); | |||
55 | ||||
56 | if (minion_sp) | |||
57 | return minion_sp->Import(type); | |||
58 | ||||
59 | return QualType(); | |||
60 | } | |||
61 | ||||
62 | lldb::clang_type_t | |||
63 | ClangASTImporter::CopyType (clang::ASTContext *dst_ast, | |||
64 | clang::ASTContext *src_ast, | |||
65 | lldb::clang_type_t type) | |||
66 | { | |||
67 | return CopyType (dst_ast, src_ast, QualType::getFromOpaquePtr(type)).getAsOpaquePtr(); | |||
68 | } | |||
69 | ||||
70 | clang::Decl * | |||
71 | ClangASTImporter::CopyDecl (clang::ASTContext *dst_ast, | |||
72 | clang::ASTContext *src_ast, | |||
73 | clang::Decl *decl) | |||
74 | { | |||
75 | MinionSP minion_sp; | |||
76 | ||||
77 | minion_sp = GetMinion(dst_ast, src_ast); | |||
78 | ||||
79 | if (minion_sp) | |||
80 | { | |||
81 | clang::Decl *result = minion_sp->Import(decl); | |||
82 | ||||
83 | if (!result) | |||
84 | { | |||
85 | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS(1u << 8))); | |||
86 | ||||
87 | if (log) | |||
88 | { | |||
89 | lldb::user_id_t user_id; | |||
90 | ClangASTMetadata *metadata = GetDeclMetadata(decl); | |||
91 | if (metadata) | |||
92 | user_id = metadata->GetUserID(); | |||
93 | ||||
94 | if (NamedDecl *named_decl = dyn_cast<NamedDecl>(decl)) | |||
95 | log->Printf(" [ClangASTImporter] WARNING: Failed to import a %s '%s', metadata 0x%" PRIx64"l" "x", | |||
96 | decl->getDeclKindName(), | |||
97 | named_decl->getNameAsString().c_str(), | |||
98 | user_id); | |||
99 | else | |||
100 | log->Printf(" [ClangASTImporter] WARNING: Failed to import a %s, metadata 0x%" PRIx64"l" "x", | |||
| ||||
101 | decl->getDeclKindName(), | |||
102 | user_id); | |||
103 | } | |||
104 | } | |||
105 | ||||
106 | return result; | |||
107 | } | |||
108 | ||||
109 | return nullptr; | |||
110 | } | |||
111 | ||||
112 | lldb::clang_type_t | |||
113 | ClangASTImporter::DeportType (clang::ASTContext *dst_ctx, | |||
114 | clang::ASTContext *src_ctx, | |||
115 | lldb::clang_type_t type) | |||
116 | { | |||
117 | MinionSP minion_sp (GetMinion (dst_ctx, src_ctx)); | |||
118 | ||||
119 | if (!minion_sp) | |||
120 | return nullptr; | |||
121 | ||||
122 | std::set<NamedDecl *> decls_to_deport; | |||
123 | std::set<NamedDecl *> decls_already_deported; | |||
124 | ||||
125 | minion_sp->InitDeportWorkQueues(&decls_to_deport, | |||
126 | &decls_already_deported); | |||
127 | ||||
128 | lldb::clang_type_t result = CopyType(dst_ctx, src_ctx, type); | |||
129 | ||||
130 | minion_sp->ExecuteDeportWorkQueues(); | |||
131 | ||||
132 | if (!result) | |||
133 | return nullptr; | |||
134 | ||||
135 | return result; | |||
136 | ||||
137 | } | |||
138 | ||||
139 | clang::Decl * | |||
140 | ClangASTImporter::DeportDecl (clang::ASTContext *dst_ctx, | |||
141 | clang::ASTContext *src_ctx, | |||
142 | clang::Decl *decl) | |||
143 | { | |||
144 | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS(1u << 8))); | |||
145 | ||||
146 | if (log) | |||
| ||||
147 | log->Printf(" [ClangASTImporter] DeportDecl called on (%sDecl*)%p from (ASTContext*)%p to (ASTContex*)%p", | |||
148 | decl->getDeclKindName(), static_cast<void*>(decl), | |||
149 | static_cast<void*>(src_ctx), | |||
150 | static_cast<void*>(dst_ctx)); | |||
151 | ||||
152 | MinionSP minion_sp (GetMinion (dst_ctx, src_ctx)); | |||
153 | ||||
154 | if (!minion_sp) | |||
155 | return nullptr; | |||
156 | ||||
157 | std::set<NamedDecl *> decls_to_deport; | |||
158 | std::set<NamedDecl *> decls_already_deported; | |||
159 | ||||
160 | minion_sp->InitDeportWorkQueues(&decls_to_deport, | |||
161 | &decls_already_deported); | |||
162 | ||||
163 | clang::Decl *result = CopyDecl(dst_ctx, src_ctx, decl); | |||
164 | ||||
165 | minion_sp->ExecuteDeportWorkQueues(); | |||
166 | ||||
167 | if (!result) | |||
168 | return nullptr; | |||
169 | ||||
170 | if (log) | |||
171 | log->Printf(" [ClangASTImporter] DeportDecl deported (%sDecl*)%p to (%sDecl*)%p", | |||
172 | decl->getDeclKindName(), static_cast<void*>(decl), | |||
173 | result->getDeclKindName(), static_cast<void*>(result)); | |||
174 | ||||
175 | return result; | |||
176 | } | |||
177 | ||||
178 | void | |||
179 | ClangASTImporter::CompleteDecl (clang::Decl *decl) | |||
180 | { | |||
181 | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS(1u << 8))); | |||
182 | ||||
183 | if (log) | |||
184 | log->Printf(" [ClangASTImporter] CompleteDecl called on (%sDecl*)%p", | |||
185 | decl->getDeclKindName(), static_cast<void*>(decl)); | |||
186 | ||||
187 | if (ObjCInterfaceDecl *interface_decl = dyn_cast<ObjCInterfaceDecl>(decl)) | |||
188 | { | |||
189 | if (!interface_decl->getDefinition()) | |||
190 | { | |||
191 | interface_decl->startDefinition(); | |||
192 | CompleteObjCInterfaceDecl(interface_decl); | |||
193 | } | |||
194 | } | |||
195 | else if (ObjCProtocolDecl *protocol_decl = dyn_cast<ObjCProtocolDecl>(decl)) | |||
196 | { | |||
197 | if (!protocol_decl->getDefinition()) | |||
198 | protocol_decl->startDefinition(); | |||
199 | } | |||
200 | else if (TagDecl *tag_decl = dyn_cast<TagDecl>(decl)) | |||
201 | { | |||
202 | if (!tag_decl->getDefinition() && !tag_decl->isBeingDefined()) | |||
203 | { | |||
204 | tag_decl->startDefinition(); | |||
205 | CompleteTagDecl(tag_decl); | |||
206 | tag_decl->setCompleteDefinition(true); | |||
207 | } | |||
208 | } | |||
209 | else | |||
210 | { | |||
211 | assert (0 && "CompleteDecl called on a Decl that can't be completed")((0 && "CompleteDecl called on a Decl that can't be completed" ) ? static_cast<void> (0) : __assert_fail ("0 && \"CompleteDecl called on a Decl that can't be completed\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn219601/tools/lldb/source/Symbol/ClangASTImporter.cpp" , 211, __PRETTY_FUNCTION__)); | |||
212 | } | |||
213 | } | |||
214 | ||||
215 | bool | |||
216 | ClangASTImporter::CompleteTagDecl (clang::TagDecl *decl) | |||
217 | { | |||
218 | ClangASTMetrics::RegisterDeclCompletion(); | |||
219 | ||||
220 | DeclOrigin decl_origin = GetDeclOrigin(decl); | |||
221 | ||||
222 | if (!decl_origin.Valid()) | |||
223 | return false; | |||
224 | ||||
225 | if (!ClangASTContext::GetCompleteDecl(decl_origin.ctx, decl_origin.decl)) | |||
226 | return false; | |||
227 | ||||
228 | MinionSP minion_sp (GetMinion(&decl->getASTContext(), decl_origin.ctx)); | |||
229 | ||||
230 | if (minion_sp) | |||
231 | minion_sp->ImportDefinitionTo(decl, decl_origin.decl); | |||
232 | ||||
233 | return true; | |||
234 | } | |||
235 | ||||
236 | bool | |||
237 | ClangASTImporter::CompleteTagDeclWithOrigin(clang::TagDecl *decl, clang::TagDecl *origin_decl) | |||
238 | { | |||
239 | ClangASTMetrics::RegisterDeclCompletion(); | |||
240 | ||||
241 | clang::ASTContext *origin_ast_ctx = &origin_decl->getASTContext(); | |||
242 | ||||
243 | if (!ClangASTContext::GetCompleteDecl(origin_ast_ctx, origin_decl)) | |||
244 | return false; | |||
245 | ||||
246 | MinionSP minion_sp (GetMinion(&decl->getASTContext(), origin_ast_ctx)); | |||
247 | ||||
248 | if (minion_sp) | |||
249 | minion_sp->ImportDefinitionTo(decl, origin_decl); | |||
250 | ||||
251 | ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext()); | |||
252 | ||||
253 | OriginMap &origins = context_md->m_origins; | |||
254 | ||||
255 | origins[decl] = DeclOrigin(origin_ast_ctx, origin_decl); | |||
256 | ||||
257 | return true; | |||
258 | } | |||
259 | ||||
260 | bool | |||
261 | ClangASTImporter::CompleteObjCInterfaceDecl (clang::ObjCInterfaceDecl *interface_decl) | |||
262 | { | |||
263 | ClangASTMetrics::RegisterDeclCompletion(); | |||
264 | ||||
265 | DeclOrigin decl_origin = GetDeclOrigin(interface_decl); | |||
266 | ||||
267 | if (!decl_origin.Valid()) | |||
268 | return false; | |||
269 | ||||
270 | if (!ClangASTContext::GetCompleteDecl(decl_origin.ctx, decl_origin.decl)) | |||
271 | return false; | |||
272 | ||||
273 | MinionSP minion_sp (GetMinion(&interface_decl->getASTContext(), decl_origin.ctx)); | |||
274 | ||||
275 | if (minion_sp) | |||
276 | minion_sp->ImportDefinitionTo(interface_decl, decl_origin.decl); | |||
277 | ||||
278 | return true; | |||
279 | } | |||
280 | ||||
281 | bool | |||
282 | ClangASTImporter::RequireCompleteType (clang::QualType type) | |||
283 | { | |||
284 | if (type.isNull()) | |||
285 | return false; | |||
286 | ||||
287 | if (const TagType *tag_type = type->getAs<TagType>()) | |||
288 | { | |||
289 | return CompleteTagDecl(tag_type->getDecl()); | |||
290 | } | |||
291 | if (const ObjCObjectType *objc_object_type = type->getAs<ObjCObjectType>()) | |||
292 | { | |||
293 | if (ObjCInterfaceDecl *objc_interface_decl = objc_object_type->getInterface()) | |||
294 | return CompleteObjCInterfaceDecl(objc_interface_decl); | |||
295 | else | |||
296 | return false; | |||
297 | } | |||
298 | if (const ArrayType *array_type = type->getAsArrayTypeUnsafe()) | |||
299 | { | |||
300 | return RequireCompleteType(array_type->getElementType()); | |||
301 | } | |||
302 | if (const AtomicType *atomic_type = type->getAs<AtomicType>()) | |||
303 | { | |||
304 | return RequireCompleteType(atomic_type->getPointeeType()); | |||
305 | } | |||
306 | ||||
307 | return true; | |||
308 | } | |||
309 | ||||
310 | ClangASTMetadata * | |||
311 | ClangASTImporter::GetDeclMetadata (const clang::Decl *decl) | |||
312 | { | |||
313 | DeclOrigin decl_origin = GetDeclOrigin(decl); | |||
314 | ||||
315 | if (decl_origin.Valid()) | |||
316 | return ClangASTContext::GetMetadata(decl_origin.ctx, decl_origin.decl); | |||
317 | else | |||
318 | return ClangASTContext::GetMetadata(&decl->getASTContext(), decl); | |||
319 | } | |||
320 | ||||
321 | ClangASTImporter::DeclOrigin | |||
322 | ClangASTImporter::GetDeclOrigin(const clang::Decl *decl) | |||
323 | { | |||
324 | ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext()); | |||
325 | ||||
326 | OriginMap &origins = context_md->m_origins; | |||
327 | ||||
328 | OriginMap::iterator iter = origins.find(decl); | |||
329 | ||||
330 | if (iter != origins.end()) | |||
331 | return iter->second; | |||
332 | else | |||
333 | return DeclOrigin(); | |||
334 | } | |||
335 | ||||
336 | void | |||
337 | ClangASTImporter::SetDeclOrigin (const clang::Decl *decl, clang::Decl *original_decl) | |||
338 | { | |||
339 | ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext()); | |||
340 | ||||
341 | OriginMap &origins = context_md->m_origins; | |||
342 | ||||
343 | OriginMap::iterator iter = origins.find(decl); | |||
344 | ||||
345 | if (iter != origins.end()) | |||
346 | { | |||
347 | iter->second.decl = original_decl; | |||
348 | iter->second.ctx = &original_decl->getASTContext(); | |||
349 | } | |||
350 | else | |||
351 | { | |||
352 | origins[decl] = DeclOrigin(&original_decl->getASTContext(), original_decl); | |||
353 | } | |||
354 | } | |||
355 | ||||
356 | void | |||
357 | ClangASTImporter::RegisterNamespaceMap(const clang::NamespaceDecl *decl, | |||
358 | NamespaceMapSP &namespace_map) | |||
359 | { | |||
360 | ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext()); | |||
361 | ||||
362 | context_md->m_namespace_maps[decl] = namespace_map; | |||
363 | } | |||
364 | ||||
365 | ClangASTImporter::NamespaceMapSP | |||
366 | ClangASTImporter::GetNamespaceMap(const clang::NamespaceDecl *decl) | |||
367 | { | |||
368 | ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext()); | |||
369 | ||||
370 | NamespaceMetaMap &namespace_maps = context_md->m_namespace_maps; | |||
371 | ||||
372 | NamespaceMetaMap::iterator iter = namespace_maps.find(decl); | |||
373 | ||||
374 | if (iter != namespace_maps.end()) | |||
375 | return iter->second; | |||
376 | else | |||
377 | return NamespaceMapSP(); | |||
378 | } | |||
379 | ||||
380 | void | |||
381 | ClangASTImporter::BuildNamespaceMap(const clang::NamespaceDecl *decl) | |||
382 | { | |||
383 | assert (decl)((decl) ? static_cast<void> (0) : __assert_fail ("decl" , "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn219601/tools/lldb/source/Symbol/ClangASTImporter.cpp" , 383, __PRETTY_FUNCTION__)); | |||
384 | ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext()); | |||
385 | ||||
386 | const DeclContext *parent_context = decl->getDeclContext(); | |||
387 | const NamespaceDecl *parent_namespace = dyn_cast<NamespaceDecl>(parent_context); | |||
388 | NamespaceMapSP parent_map; | |||
389 | ||||
390 | if (parent_namespace) | |||
391 | parent_map = GetNamespaceMap(parent_namespace); | |||
392 | ||||
393 | NamespaceMapSP new_map; | |||
394 | ||||
395 | new_map.reset(new NamespaceMap); | |||
396 | ||||
397 | if (context_md->m_map_completer) | |||
398 | { | |||
399 | std::string namespace_string = decl->getDeclName().getAsString(); | |||
400 | ||||
401 | context_md->m_map_completer->CompleteNamespaceMap (new_map, ConstString(namespace_string.c_str()), parent_map); | |||
402 | } | |||
403 | ||||
404 | context_md->m_namespace_maps[decl] = new_map; | |||
405 | } | |||
406 | ||||
407 | void | |||
408 | ClangASTImporter::ForgetDestination (clang::ASTContext *dst_ast) | |||
409 | { | |||
410 | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS(1u << 8))); | |||
411 | ||||
412 | if (log) | |||
413 | log->Printf(" [ClangASTImporter] Forgetting destination (ASTContext*)%p", | |||
414 | static_cast<void*>(dst_ast)); | |||
415 | ||||
416 | m_metadata_map.erase(dst_ast); | |||
417 | } | |||
418 | ||||
419 | void | |||
420 | ClangASTImporter::ForgetSource (clang::ASTContext *dst_ast, clang::ASTContext *src_ast) | |||
421 | { | |||
422 | ASTContextMetadataSP md = MaybeGetContextMetadata (dst_ast); | |||
423 | ||||
424 | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS(1u << 8))); | |||
425 | ||||
426 | if (log) | |||
427 | log->Printf(" [ClangASTImporter] Forgetting source->dest (ASTContext*)%p->(ASTContext*)%p", | |||
428 | static_cast<void*>(src_ast), static_cast<void*>(dst_ast)); | |||
429 | ||||
430 | if (!md) | |||
431 | return; | |||
432 | ||||
433 | md->m_minions.erase(src_ast); | |||
434 | ||||
435 | for (OriginMap::iterator iter = md->m_origins.begin(); | |||
436 | iter != md->m_origins.end(); | |||
437 | ) | |||
438 | { | |||
439 | if (iter->second.ctx == src_ast) | |||
440 | md->m_origins.erase(iter++); | |||
441 | else | |||
442 | ++iter; | |||
443 | } | |||
444 | } | |||
445 | ||||
446 | ClangASTImporter::MapCompleter::~MapCompleter () | |||
447 | { | |||
448 | return; | |||
449 | } | |||
450 | ||||
451 | void | |||
452 | ClangASTImporter::Minion::InitDeportWorkQueues (std::set<clang::NamedDecl *> *decls_to_deport, | |||
453 | std::set<clang::NamedDecl *> *decls_already_deported) | |||
454 | { | |||
455 | assert(!m_decls_to_deport)((!m_decls_to_deport) ? static_cast<void> (0) : __assert_fail ("!m_decls_to_deport", "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn219601/tools/lldb/source/Symbol/ClangASTImporter.cpp" , 455, __PRETTY_FUNCTION__)); // TODO make debug only | |||
456 | assert(!m_decls_already_deported)((!m_decls_already_deported) ? static_cast<void> (0) : __assert_fail ("!m_decls_already_deported", "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn219601/tools/lldb/source/Symbol/ClangASTImporter.cpp" , 456, __PRETTY_FUNCTION__)); | |||
457 | ||||
458 | m_decls_to_deport = decls_to_deport; | |||
459 | m_decls_already_deported = decls_already_deported; | |||
460 | } | |||
461 | ||||
462 | void | |||
463 | ClangASTImporter::Minion::ExecuteDeportWorkQueues () | |||
464 | { | |||
465 | assert(m_decls_to_deport)((m_decls_to_deport) ? static_cast<void> (0) : __assert_fail ("m_decls_to_deport", "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn219601/tools/lldb/source/Symbol/ClangASTImporter.cpp" , 465, __PRETTY_FUNCTION__)); // TODO make debug only | |||
466 | assert(m_decls_already_deported)((m_decls_already_deported) ? static_cast<void> (0) : __assert_fail ("m_decls_already_deported", "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn219601/tools/lldb/source/Symbol/ClangASTImporter.cpp" , 466, __PRETTY_FUNCTION__)); | |||
467 | ||||
468 | ASTContextMetadataSP to_context_md = m_master.GetContextMetadata(&getToContext()); | |||
469 | ||||
470 | while (!m_decls_to_deport->empty()) | |||
471 | { | |||
472 | NamedDecl *decl = *m_decls_to_deport->begin(); | |||
473 | ||||
474 | m_decls_already_deported->insert(decl); | |||
475 | m_decls_to_deport->erase(decl); | |||
476 | ||||
477 | DeclOrigin &origin = to_context_md->m_origins[decl]; | |||
478 | ||||
479 | assert (origin.ctx == m_source_ctx)((origin.ctx == m_source_ctx) ? static_cast<void> (0) : __assert_fail ("origin.ctx == m_source_ctx", "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn219601/tools/lldb/source/Symbol/ClangASTImporter.cpp" , 479, __PRETTY_FUNCTION__)); // otherwise we should never have added this | |||
480 | // because it doesn't need to be deported | |||
481 | ||||
482 | Decl *original_decl = to_context_md->m_origins[decl].decl; | |||
483 | ||||
484 | ClangASTContext::GetCompleteDecl (m_source_ctx, original_decl); | |||
485 | ||||
486 | if (TagDecl *tag_decl = dyn_cast<TagDecl>(decl)) | |||
487 | { | |||
488 | if (TagDecl *original_tag_decl = dyn_cast<TagDecl>(original_decl)) | |||
489 | if (original_tag_decl->isCompleteDefinition()) | |||
490 | ImportDefinitionTo(tag_decl, original_tag_decl); | |||
491 | ||||
492 | tag_decl->setHasExternalLexicalStorage(false); | |||
493 | tag_decl->setHasExternalVisibleStorage(false); | |||
494 | } | |||
495 | else if (ObjCInterfaceDecl *interface_decl = dyn_cast<ObjCInterfaceDecl>(decl)) | |||
496 | { | |||
497 | interface_decl->setHasExternalLexicalStorage(false); | |||
498 | interface_decl->setHasExternalVisibleStorage(false); | |||
499 | } | |||
500 | ||||
501 | to_context_md->m_origins.erase(decl); | |||
502 | } | |||
503 | ||||
504 | m_decls_to_deport = nullptr; | |||
505 | m_decls_already_deported = nullptr; | |||
506 | } | |||
507 | ||||
508 | void | |||
509 | ClangASTImporter::Minion::ImportDefinitionTo (clang::Decl *to, clang::Decl *from) | |||
510 | { | |||
511 | ASTImporter::Imported(from, to); | |||
512 | ||||
513 | ObjCInterfaceDecl *to_objc_interface = dyn_cast<ObjCInterfaceDecl>(to); | |||
514 | ||||
515 | /* | |||
516 | if (to_objc_interface) | |||
517 | to_objc_interface->startDefinition(); | |||
518 | ||||
519 | CXXRecordDecl *to_cxx_record = dyn_cast<CXXRecordDecl>(to); | |||
520 | ||||
521 | if (to_cxx_record) | |||
522 | to_cxx_record->startDefinition(); | |||
523 | */ | |||
524 | ||||
525 | ImportDefinition(from); | |||
526 | ||||
527 | // If we're dealing with an Objective-C class, ensure that the inheritance has | |||
528 | // been set up correctly. The ASTImporter may not do this correctly if the | |||
529 | // class was originally sourced from symbols. | |||
530 | ||||
531 | if (to_objc_interface) | |||
532 | { | |||
533 | do | |||
534 | { | |||
535 | ObjCInterfaceDecl *to_superclass = to_objc_interface->getSuperClass(); | |||
536 | ||||
537 | if (to_superclass) | |||
538 | break; // we're not going to override it if it's set | |||
539 | ||||
540 | ObjCInterfaceDecl *from_objc_interface = dyn_cast<ObjCInterfaceDecl>(from); | |||
541 | ||||
542 | if (!from_objc_interface) | |||
543 | break; | |||
544 | ||||
545 | ObjCInterfaceDecl *from_superclass = from_objc_interface->getSuperClass(); | |||
546 | ||||
547 | if (!from_superclass) | |||
548 | break; | |||
549 | ||||
550 | Decl *imported_from_superclass_decl = Import(from_superclass); | |||
551 | ||||
552 | if (!imported_from_superclass_decl) | |||
553 | break; | |||
554 | ||||
555 | ObjCInterfaceDecl *imported_from_superclass = dyn_cast<ObjCInterfaceDecl>(imported_from_superclass_decl); | |||
556 | ||||
557 | if (!imported_from_superclass) | |||
558 | break; | |||
559 | ||||
560 | if (!to_objc_interface->hasDefinition()) | |||
561 | to_objc_interface->startDefinition(); | |||
562 | ||||
563 | to_objc_interface->setSuperClass(imported_from_superclass); | |||
564 | } | |||
565 | while (0); | |||
566 | } | |||
567 | } | |||
568 | ||||
569 | clang::Decl * | |||
570 | ClangASTImporter::Minion::Imported (clang::Decl *from, clang::Decl *to) | |||
571 | { | |||
572 | ClangASTMetrics::RegisterClangImport(); | |||
573 | ||||
574 | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS(1u << 8))); | |||
575 | ||||
576 | lldb::user_id_t user_id = LLDB_INVALID_UID(18446744073709551615UL); | |||
577 | ClangASTMetadata *metadata = m_master.GetDeclMetadata(from); | |||
578 | if (metadata) | |||
579 | user_id = metadata->GetUserID(); | |||
580 | ||||
581 | if (log) | |||
582 | { | |||
583 | if (NamedDecl *from_named_decl = dyn_cast<clang::NamedDecl>(from)) | |||
584 | { | |||
585 | std::string name_string; | |||
586 | llvm::raw_string_ostream name_stream(name_string); | |||
587 | from_named_decl->printName(name_stream); | |||
588 | name_stream.flush(); | |||
589 | ||||
590 | log->Printf(" [ClangASTImporter] Imported (%sDecl*)%p, named %s (from (Decl*)%p), metadata 0x%" PRIx64"l" "x", | |||
591 | from->getDeclKindName(), static_cast<void*>(to), | |||
592 | name_string.c_str(), static_cast<void*>(from), | |||
593 | user_id); | |||
594 | } | |||
595 | else | |||
596 | { | |||
597 | log->Printf(" [ClangASTImporter] Imported (%sDecl*)%p (from (Decl*)%p), metadata 0x%" PRIx64"l" "x", | |||
598 | from->getDeclKindName(), static_cast<void*>(to), | |||
599 | static_cast<void*>(from), user_id); | |||
600 | } | |||
601 | } | |||
602 | ||||
603 | ASTContextMetadataSP to_context_md = m_master.GetContextMetadata(&to->getASTContext()); | |||
604 | ASTContextMetadataSP from_context_md = m_master.MaybeGetContextMetadata(m_source_ctx); | |||
605 | ||||
606 | if (from_context_md) | |||
607 | { | |||
608 | OriginMap &origins = from_context_md->m_origins; | |||
609 | ||||
610 | OriginMap::iterator origin_iter = origins.find(from); | |||
611 | ||||
612 | if (origin_iter != origins.end()) | |||
613 | { | |||
614 | if (to_context_md->m_origins.find(to) == to_context_md->m_origins.end() || | |||
615 | user_id != LLDB_INVALID_UID(18446744073709551615UL)) | |||
616 | { | |||
617 | to_context_md->m_origins[to] = origin_iter->second; | |||
618 | } | |||
619 | ||||
620 | MinionSP direct_completer = m_master.GetMinion(&to->getASTContext(), origin_iter->second.ctx); | |||
621 | ||||
622 | if (direct_completer.get() != this) | |||
623 | direct_completer->ASTImporter::Imported(origin_iter->second.decl, to); | |||
624 | ||||
625 | if (log) | |||
626 | log->Printf(" [ClangASTImporter] Propagated origin (Decl*)%p/(ASTContext*)%p from (ASTContext*)%p to (ASTContext*)%p", | |||
627 | static_cast<void*>(origin_iter->second.decl), | |||
628 | static_cast<void*>(origin_iter->second.ctx), | |||
629 | static_cast<void*>(&from->getASTContext()), | |||
630 | static_cast<void*>(&to->getASTContext())); | |||
631 | } | |||
632 | else | |||
633 | { | |||
634 | if (m_decls_to_deport && m_decls_already_deported) | |||
635 | { | |||
636 | if (isa<TagDecl>(to) || isa<ObjCInterfaceDecl>(to)) | |||
637 | { | |||
638 | NamedDecl *to_named_decl = dyn_cast<NamedDecl>(to); | |||
639 | ||||
640 | if (!m_decls_already_deported->count(to_named_decl)) | |||
641 | m_decls_to_deport->insert(to_named_decl); | |||
642 | } | |||
643 | } | |||
644 | ||||
645 | if (to_context_md->m_origins.find(to) == to_context_md->m_origins.end() || | |||
646 | user_id != LLDB_INVALID_UID(18446744073709551615UL)) | |||
647 | { | |||
648 | to_context_md->m_origins[to] = DeclOrigin(m_source_ctx, from); | |||
649 | } | |||
650 | ||||
651 | if (log) | |||
652 | log->Printf(" [ClangASTImporter] Decl has no origin information in (ASTContext*)%p", | |||
653 | static_cast<void*>(&from->getASTContext())); | |||
654 | } | |||
655 | ||||
656 | if (clang::NamespaceDecl *to_namespace = dyn_cast<clang::NamespaceDecl>(to)) | |||
657 | { | |||
658 | clang::NamespaceDecl *from_namespace = dyn_cast<clang::NamespaceDecl>(from); | |||
659 | ||||
660 | NamespaceMetaMap &namespace_maps = from_context_md->m_namespace_maps; | |||
661 | ||||
662 | NamespaceMetaMap::iterator namespace_map_iter = namespace_maps.find(from_namespace); | |||
663 | ||||
664 | if (namespace_map_iter != namespace_maps.end()) | |||
665 | to_context_md->m_namespace_maps[to_namespace] = namespace_map_iter->second; | |||
666 | } | |||
667 | } | |||
668 | else | |||
669 | { | |||
670 | to_context_md->m_origins[to] = DeclOrigin (m_source_ctx, from); | |||
671 | ||||
672 | if (log) | |||
673 | log->Printf(" [ClangASTImporter] Sourced origin (Decl*)%p/(ASTContext*)%p into (ASTContext*)%p", | |||
674 | static_cast<void*>(from), | |||
675 | static_cast<void*>(m_source_ctx), | |||
676 | static_cast<void*>(&to->getASTContext())); | |||
677 | } | |||
678 | ||||
679 | if (TagDecl *from_tag_decl = dyn_cast<TagDecl>(from)) | |||
680 | { | |||
681 | TagDecl *to_tag_decl = dyn_cast<TagDecl>(to); | |||
682 | ||||
683 | to_tag_decl->setHasExternalLexicalStorage(); | |||
684 | to_tag_decl->setMustBuildLookupTable(); | |||
685 | ||||
686 | if (log) | |||
687 | log->Printf(" [ClangASTImporter] To is a TagDecl - attributes %s%s [%s->%s]", | |||
688 | (to_tag_decl->hasExternalLexicalStorage() ? " Lexical" : ""), | |||
689 | (to_tag_decl->hasExternalVisibleStorage() ? " Visible" : ""), | |||
690 | (from_tag_decl->isCompleteDefinition() ? "complete" : "incomplete"), | |||
691 | (to_tag_decl->isCompleteDefinition() ? "complete" : "incomplete")); | |||
692 | } | |||
693 | ||||
694 | if (isa<NamespaceDecl>(from)) | |||
695 | { | |||
696 | NamespaceDecl *to_namespace_decl = dyn_cast<NamespaceDecl>(to); | |||
697 | ||||
698 | m_master.BuildNamespaceMap(to_namespace_decl); | |||
699 | ||||
700 | to_namespace_decl->setHasExternalVisibleStorage(); | |||
701 | } | |||
702 | ||||
703 | if (isa<ObjCInterfaceDecl>(from)) | |||
704 | { | |||
705 | ObjCInterfaceDecl *to_interface_decl = dyn_cast<ObjCInterfaceDecl>(to); | |||
706 | ||||
707 | to_interface_decl->setHasExternalLexicalStorage(); | |||
708 | to_interface_decl->setHasExternalVisibleStorage(); | |||
709 | ||||
710 | /*to_interface_decl->setExternallyCompleted();*/ | |||
711 | ||||
712 | if (log) | |||
713 | log->Printf(" [ClangASTImporter] To is an ObjCInterfaceDecl - attributes %s%s%s", | |||
714 | (to_interface_decl->hasExternalLexicalStorage() ? " Lexical" : ""), | |||
715 | (to_interface_decl->hasExternalVisibleStorage() ? " Visible" : ""), | |||
716 | (to_interface_decl->hasDefinition() ? " HasDefinition" : "")); | |||
717 | } | |||
718 | ||||
719 | return clang::ASTImporter::Imported(from, to); | |||
720 | } | |||
721 | ||||
722 | clang::Decl *ClangASTImporter::Minion::GetOriginalDecl (clang::Decl *To) | |||
723 | { | |||
724 | ASTContextMetadataSP to_context_md = m_master.GetContextMetadata(&To->getASTContext()); | |||
725 | ||||
726 | if (!to_context_md) | |||
727 | return nullptr; | |||
728 | ||||
729 | OriginMap::iterator iter = to_context_md->m_origins.find(To); | |||
730 | ||||
731 | if (iter == to_context_md->m_origins.end()) | |||
732 | return nullptr; | |||
733 | ||||
734 | return const_cast<clang::Decl*>(iter->second.decl); | |||
735 | } |