File: | tools/lldb/source/Symbol/ClangASTImporter.cpp |
Location: | line 259, column 13 |
Description: | Dereference of undefined pointer 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/Utility/LLDBAssert.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::opaque_compiler_type_t | |||
63 | ClangASTImporter::CopyType (clang::ASTContext *dst_ast, | |||
64 | clang::ASTContext *src_ast, | |||
65 | lldb::opaque_compiler_type_t type) | |||
66 | { | |||
67 | return CopyType (dst_ast, src_ast, QualType::getFromOpaquePtr(type)).getAsOpaquePtr(); | |||
68 | } | |||
69 | ||||
70 | CompilerType | |||
71 | ClangASTImporter::CopyType (ClangASTContext &dst_ast, | |||
72 | const CompilerType &src_type) | |||
73 | { | |||
74 | clang::ASTContext *dst_clang_ast = dst_ast.getASTContext(); | |||
75 | if (dst_clang_ast) | |||
76 | { | |||
77 | ClangASTContext *src_ast = llvm::dyn_cast_or_null<ClangASTContext>(src_type.GetTypeSystem()); | |||
78 | if (src_ast) | |||
79 | { | |||
80 | clang::ASTContext *src_clang_ast = src_ast->getASTContext(); | |||
81 | if (src_clang_ast) | |||
82 | { | |||
83 | lldb::opaque_compiler_type_t dst_clang_type = CopyType(dst_clang_ast, | |||
84 | src_clang_ast, | |||
85 | src_type.GetOpaqueQualType()); | |||
86 | ||||
87 | if (dst_clang_type) | |||
88 | return CompilerType(&dst_ast, dst_clang_type); | |||
89 | } | |||
90 | } | |||
91 | } | |||
92 | return CompilerType(); | |||
93 | } | |||
94 | ||||
95 | clang::Decl * | |||
96 | ClangASTImporter::CopyDecl (clang::ASTContext *dst_ast, | |||
97 | clang::ASTContext *src_ast, | |||
98 | clang::Decl *decl) | |||
99 | { | |||
100 | MinionSP minion_sp; | |||
101 | ||||
102 | minion_sp = GetMinion(dst_ast, src_ast); | |||
103 | ||||
104 | if (minion_sp) | |||
105 | { | |||
106 | clang::Decl *result = minion_sp->Import(decl); | |||
107 | ||||
108 | if (!result) | |||
109 | { | |||
110 | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS(1u << 8))); | |||
111 | ||||
112 | if (log) | |||
113 | { | |||
114 | lldb::user_id_t user_id = LLDB_INVALID_UID(18446744073709551615UL); | |||
115 | ClangASTMetadata *metadata = GetDeclMetadata(decl); | |||
116 | if (metadata) | |||
117 | user_id = metadata->GetUserID(); | |||
118 | ||||
119 | if (NamedDecl *named_decl = dyn_cast<NamedDecl>(decl)) | |||
120 | log->Printf(" [ClangASTImporter] WARNING: Failed to import a %s '%s', metadata 0x%" PRIx64"l" "x", | |||
121 | decl->getDeclKindName(), | |||
122 | named_decl->getNameAsString().c_str(), | |||
123 | user_id); | |||
124 | else | |||
125 | log->Printf(" [ClangASTImporter] WARNING: Failed to import a %s, metadata 0x%" PRIx64"l" "x", | |||
126 | decl->getDeclKindName(), | |||
127 | user_id); | |||
128 | } | |||
129 | } | |||
130 | ||||
131 | return result; | |||
132 | } | |||
133 | ||||
134 | return nullptr; | |||
135 | } | |||
136 | ||||
137 | class DeclContextOverride | |||
138 | { | |||
139 | private: | |||
140 | struct Backup | |||
141 | { | |||
142 | clang::DeclContext *decl_context; | |||
143 | clang::DeclContext *lexical_decl_context; | |||
144 | }; | |||
145 | ||||
146 | std::map<clang::Decl *, Backup> m_backups; | |||
147 | ||||
148 | void OverrideOne(clang::Decl *decl) | |||
149 | { | |||
150 | if (m_backups.find(decl) != m_backups.end()) | |||
151 | { | |||
152 | return; | |||
153 | } | |||
154 | ||||
155 | m_backups[decl] = { decl->getDeclContext(), decl->getLexicalDeclContext() }; | |||
156 | ||||
157 | decl->setDeclContext(decl->getASTContext().getTranslationUnitDecl()); | |||
158 | decl->setLexicalDeclContext(decl->getASTContext().getTranslationUnitDecl()); | |||
159 | } | |||
160 | ||||
161 | bool ChainPassesThrough(clang::Decl *decl, | |||
162 | clang::DeclContext *base, | |||
163 | clang::DeclContext *(clang::Decl::*contextFromDecl)(), | |||
164 | clang::DeclContext *(clang::DeclContext::*contextFromContext)()) | |||
165 | { | |||
166 | for (DeclContext *decl_ctx = (decl->*contextFromDecl)(); | |||
167 | decl_ctx; | |||
168 | decl_ctx = (decl_ctx->*contextFromContext)()) | |||
169 | { | |||
170 | if (decl_ctx == base) | |||
171 | { | |||
172 | return true; | |||
173 | } | |||
174 | } | |||
175 | ||||
176 | return false; | |||
177 | } | |||
178 | ||||
179 | clang::Decl *GetEscapedChild(clang::Decl *decl, clang::DeclContext *base = nullptr) | |||
180 | { | |||
181 | if (base) | |||
182 | { | |||
183 | // decl's DeclContext chains must pass through base. | |||
184 | ||||
185 | if (!ChainPassesThrough(decl, base, &clang::Decl::getDeclContext, &clang::DeclContext::getParent) || | |||
186 | !ChainPassesThrough(decl, base, &clang::Decl::getLexicalDeclContext, &clang::DeclContext::getLexicalParent)) | |||
187 | { | |||
188 | return decl; | |||
189 | } | |||
190 | } | |||
191 | else | |||
192 | { | |||
193 | base = clang::dyn_cast<clang::DeclContext>(decl); | |||
194 | ||||
195 | if (!base) | |||
196 | { | |||
197 | return nullptr; | |||
198 | } | |||
199 | } | |||
200 | ||||
201 | if (clang::DeclContext *context = clang::dyn_cast<clang::DeclContext>(decl)) | |||
202 | { | |||
203 | for (clang::Decl *decl : context->decls()) | |||
204 | { | |||
205 | if (clang::Decl *escaped_child = GetEscapedChild(decl)) | |||
206 | { | |||
207 | return escaped_child; | |||
208 | } | |||
209 | } | |||
210 | } | |||
211 | ||||
212 | return nullptr; | |||
213 | } | |||
214 | ||||
215 | void Override(clang::Decl *decl) | |||
216 | { | |||
217 | if (clang::Decl *escaped_child = GetEscapedChild(decl)) | |||
218 | { | |||
219 | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS(1u << 8))); | |||
220 | ||||
221 | if (log) | |||
222 | log->Printf(" [ClangASTImporter] DeclContextOverride couldn't override (%sDecl*)%p - its child (%sDecl*)%p escapes", | |||
223 | decl->getDeclKindName(), static_cast<void*>(decl), | |||
224 | escaped_child->getDeclKindName(), static_cast<void*>(escaped_child)); | |||
225 | lldbassert(0 && "Couldn't override!")lldb_private::lldb_assert(0 && "Couldn't override!", "0 && \"Couldn't override!\"" , __FUNCTION__, "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn255820/tools/lldb/source/Symbol/ClangASTImporter.cpp" , 225); | |||
226 | } | |||
227 | ||||
228 | OverrideOne(decl); | |||
229 | } | |||
230 | ||||
231 | public: | |||
232 | DeclContextOverride() | |||
233 | { | |||
234 | } | |||
235 | ||||
236 | void OverrideAllDeclsFromContainingFunction(clang::Decl *decl) | |||
237 | { | |||
238 | for (DeclContext *decl_context = decl->getLexicalDeclContext(); | |||
239 | decl_context; | |||
240 | decl_context = decl_context->getLexicalParent()) | |||
241 | { | |||
242 | DeclContext *redecl_context = decl_context->getRedeclContext(); | |||
243 | ||||
244 | if (llvm::isa<FunctionDecl>(redecl_context) && | |||
245 | llvm::isa<TranslationUnitDecl>(redecl_context->getLexicalParent())) | |||
246 | { | |||
247 | for (clang::Decl *child_decl : decl_context->decls()) | |||
248 | { | |||
249 | Override(child_decl); | |||
250 | } | |||
251 | } | |||
252 | } | |||
253 | } | |||
254 | ||||
255 | ~DeclContextOverride() | |||
256 | { | |||
257 | for (const std::pair<clang::Decl *, Backup> &backup : m_backups) | |||
| ||||
258 | { | |||
259 | backup.first->setDeclContext(backup.second.decl_context); | |||
| ||||
260 | backup.first->setLexicalDeclContext(backup.second.lexical_decl_context); | |||
261 | } | |||
262 | } | |||
263 | }; | |||
264 | ||||
265 | lldb::opaque_compiler_type_t | |||
266 | ClangASTImporter::DeportType (clang::ASTContext *dst_ctx, | |||
267 | clang::ASTContext *src_ctx, | |||
268 | lldb::opaque_compiler_type_t type) | |||
269 | { | |||
270 | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS(1u << 8))); | |||
271 | ||||
272 | if (log) | |||
273 | log->Printf(" [ClangASTImporter] DeportType called on (%sType*)0x%llx from (ASTContext*)%p to (ASTContext*)%p", | |||
274 | QualType::getFromOpaquePtr(type)->getTypeClassName(), (unsigned long long)type, | |||
275 | static_cast<void*>(src_ctx), | |||
276 | static_cast<void*>(dst_ctx)); | |||
277 | ||||
278 | MinionSP minion_sp (GetMinion (dst_ctx, src_ctx)); | |||
279 | ||||
280 | if (!minion_sp) | |||
281 | return nullptr; | |||
282 | ||||
283 | std::set<NamedDecl *> decls_to_deport; | |||
284 | std::set<NamedDecl *> decls_already_deported; | |||
285 | ||||
286 | DeclContextOverride decl_context_override; | |||
287 | ||||
288 | if (const clang::TagType *tag_type = clang::QualType::getFromOpaquePtr(type)->getAs<TagType>()) | |||
289 | { | |||
290 | decl_context_override.OverrideAllDeclsFromContainingFunction(tag_type->getDecl()); | |||
291 | } | |||
292 | ||||
293 | minion_sp->InitDeportWorkQueues(&decls_to_deport, | |||
294 | &decls_already_deported); | |||
295 | ||||
296 | lldb::opaque_compiler_type_t result = CopyType(dst_ctx, src_ctx, type); | |||
297 | ||||
298 | minion_sp->ExecuteDeportWorkQueues(); | |||
299 | ||||
300 | if (!result) | |||
301 | return nullptr; | |||
302 | ||||
303 | return result; | |||
304 | ||||
305 | } | |||
306 | ||||
307 | clang::Decl * | |||
308 | ClangASTImporter::DeportDecl (clang::ASTContext *dst_ctx, | |||
309 | clang::ASTContext *src_ctx, | |||
310 | clang::Decl *decl) | |||
311 | { | |||
312 | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS(1u << 8))); | |||
313 | ||||
314 | if (log) | |||
315 | log->Printf(" [ClangASTImporter] DeportDecl called on (%sDecl*)%p from (ASTContext*)%p to (ASTContext*)%p", | |||
316 | decl->getDeclKindName(), static_cast<void*>(decl), | |||
317 | static_cast<void*>(src_ctx), | |||
318 | static_cast<void*>(dst_ctx)); | |||
319 | ||||
320 | MinionSP minion_sp (GetMinion (dst_ctx, src_ctx)); | |||
321 | ||||
322 | if (!minion_sp) | |||
323 | return nullptr; | |||
324 | ||||
325 | std::set<NamedDecl *> decls_to_deport; | |||
326 | std::set<NamedDecl *> decls_already_deported; | |||
327 | ||||
328 | DeclContextOverride decl_context_override; | |||
329 | ||||
330 | decl_context_override.OverrideAllDeclsFromContainingFunction(decl); | |||
331 | ||||
332 | minion_sp->InitDeportWorkQueues(&decls_to_deport, | |||
333 | &decls_already_deported); | |||
334 | ||||
335 | clang::Decl *result = CopyDecl(dst_ctx, src_ctx, decl); | |||
336 | ||||
337 | minion_sp->ExecuteDeportWorkQueues(); | |||
338 | ||||
339 | if (!result) | |||
340 | return nullptr; | |||
341 | ||||
342 | if (log) | |||
343 | log->Printf(" [ClangASTImporter] DeportDecl deported (%sDecl*)%p to (%sDecl*)%p", | |||
344 | decl->getDeclKindName(), static_cast<void*>(decl), | |||
345 | result->getDeclKindName(), static_cast<void*>(result)); | |||
346 | ||||
347 | return result; | |||
348 | } | |||
349 | ||||
350 | void | |||
351 | ClangASTImporter::CompleteDecl (clang::Decl *decl) | |||
352 | { | |||
353 | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS(1u << 8))); | |||
354 | ||||
355 | if (log) | |||
356 | log->Printf(" [ClangASTImporter] CompleteDecl called on (%sDecl*)%p", | |||
357 | decl->getDeclKindName(), static_cast<void*>(decl)); | |||
358 | ||||
359 | if (ObjCInterfaceDecl *interface_decl = dyn_cast<ObjCInterfaceDecl>(decl)) | |||
360 | { | |||
361 | if (!interface_decl->getDefinition()) | |||
362 | { | |||
363 | interface_decl->startDefinition(); | |||
364 | CompleteObjCInterfaceDecl(interface_decl); | |||
365 | } | |||
366 | } | |||
367 | else if (ObjCProtocolDecl *protocol_decl = dyn_cast<ObjCProtocolDecl>(decl)) | |||
368 | { | |||
369 | if (!protocol_decl->getDefinition()) | |||
370 | protocol_decl->startDefinition(); | |||
371 | } | |||
372 | else if (TagDecl *tag_decl = dyn_cast<TagDecl>(decl)) | |||
373 | { | |||
374 | if (!tag_decl->getDefinition() && !tag_decl->isBeingDefined()) | |||
375 | { | |||
376 | tag_decl->startDefinition(); | |||
377 | CompleteTagDecl(tag_decl); | |||
378 | tag_decl->setCompleteDefinition(true); | |||
379 | } | |||
380 | } | |||
381 | else | |||
382 | { | |||
383 | 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.8~svn255820/tools/lldb/source/Symbol/ClangASTImporter.cpp" , 383, __PRETTY_FUNCTION__)); | |||
384 | } | |||
385 | } | |||
386 | ||||
387 | bool | |||
388 | ClangASTImporter::CompleteTagDecl (clang::TagDecl *decl) | |||
389 | { | |||
390 | ClangASTMetrics::RegisterDeclCompletion(); | |||
391 | ||||
392 | DeclOrigin decl_origin = GetDeclOrigin(decl); | |||
393 | ||||
394 | if (!decl_origin.Valid()) | |||
395 | return false; | |||
396 | ||||
397 | if (!ClangASTContext::GetCompleteDecl(decl_origin.ctx, decl_origin.decl)) | |||
398 | return false; | |||
399 | ||||
400 | MinionSP minion_sp (GetMinion(&decl->getASTContext(), decl_origin.ctx)); | |||
401 | ||||
402 | if (minion_sp) | |||
403 | minion_sp->ImportDefinitionTo(decl, decl_origin.decl); | |||
404 | ||||
405 | return true; | |||
406 | } | |||
407 | ||||
408 | bool | |||
409 | ClangASTImporter::CompleteTagDeclWithOrigin(clang::TagDecl *decl, clang::TagDecl *origin_decl) | |||
410 | { | |||
411 | ClangASTMetrics::RegisterDeclCompletion(); | |||
412 | ||||
413 | clang::ASTContext *origin_ast_ctx = &origin_decl->getASTContext(); | |||
414 | ||||
415 | if (!ClangASTContext::GetCompleteDecl(origin_ast_ctx, origin_decl)) | |||
416 | return false; | |||
417 | ||||
418 | MinionSP minion_sp (GetMinion(&decl->getASTContext(), origin_ast_ctx)); | |||
419 | ||||
420 | if (minion_sp) | |||
421 | minion_sp->ImportDefinitionTo(decl, origin_decl); | |||
422 | ||||
423 | ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext()); | |||
424 | ||||
425 | OriginMap &origins = context_md->m_origins; | |||
426 | ||||
427 | origins[decl] = DeclOrigin(origin_ast_ctx, origin_decl); | |||
428 | ||||
429 | return true; | |||
430 | } | |||
431 | ||||
432 | bool | |||
433 | ClangASTImporter::CompleteObjCInterfaceDecl (clang::ObjCInterfaceDecl *interface_decl) | |||
434 | { | |||
435 | ClangASTMetrics::RegisterDeclCompletion(); | |||
436 | ||||
437 | DeclOrigin decl_origin = GetDeclOrigin(interface_decl); | |||
438 | ||||
439 | if (!decl_origin.Valid()) | |||
440 | return false; | |||
441 | ||||
442 | if (!ClangASTContext::GetCompleteDecl(decl_origin.ctx, decl_origin.decl)) | |||
443 | return false; | |||
444 | ||||
445 | MinionSP minion_sp (GetMinion(&interface_decl->getASTContext(), decl_origin.ctx)); | |||
446 | ||||
447 | if (minion_sp) | |||
448 | minion_sp->ImportDefinitionTo(interface_decl, decl_origin.decl); | |||
449 | ||||
450 | if (ObjCInterfaceDecl *super_class = interface_decl->getSuperClass()) | |||
451 | RequireCompleteType(clang::QualType(super_class->getTypeForDecl(), 0)); | |||
452 | ||||
453 | return true; | |||
454 | } | |||
455 | ||||
456 | bool | |||
457 | ClangASTImporter::CompleteAndFetchChildren (clang::QualType type) | |||
458 | { | |||
459 | if (!RequireCompleteType(type)) | |||
460 | return false; | |||
461 | ||||
462 | if (const TagType *tag_type = type->getAs<TagType>()) | |||
463 | { | |||
464 | TagDecl *tag_decl = tag_type->getDecl(); | |||
465 | ||||
466 | DeclOrigin decl_origin = GetDeclOrigin(tag_decl); | |||
467 | ||||
468 | if (!decl_origin.Valid()) | |||
469 | return false; | |||
470 | ||||
471 | MinionSP minion_sp (GetMinion(&tag_decl->getASTContext(), decl_origin.ctx)); | |||
472 | ||||
473 | TagDecl *origin_tag_decl = llvm::dyn_cast<TagDecl>(decl_origin.decl); | |||
474 | ||||
475 | for (Decl *origin_child_decl : origin_tag_decl->decls()) | |||
476 | { | |||
477 | minion_sp->Import(origin_child_decl); | |||
478 | } | |||
479 | ||||
480 | if (RecordDecl *record_decl = dyn_cast<RecordDecl>(origin_tag_decl)) | |||
481 | { | |||
482 | record_decl->setHasLoadedFieldsFromExternalStorage(true); | |||
483 | } | |||
484 | ||||
485 | return true; | |||
486 | } | |||
487 | ||||
488 | if (const ObjCObjectType *objc_object_type = type->getAs<ObjCObjectType>()) | |||
489 | { | |||
490 | if (ObjCInterfaceDecl *objc_interface_decl = objc_object_type->getInterface()) | |||
491 | { | |||
492 | DeclOrigin decl_origin = GetDeclOrigin(objc_interface_decl); | |||
493 | ||||
494 | if (!decl_origin.Valid()) | |||
495 | return false; | |||
496 | ||||
497 | MinionSP minion_sp (GetMinion(&objc_interface_decl->getASTContext(), decl_origin.ctx)); | |||
498 | ||||
499 | ObjCInterfaceDecl *origin_interface_decl = llvm::dyn_cast<ObjCInterfaceDecl>(decl_origin.decl); | |||
500 | ||||
501 | for (Decl *origin_child_decl : origin_interface_decl->decls()) | |||
502 | { | |||
503 | minion_sp->Import(origin_child_decl); | |||
504 | } | |||
505 | ||||
506 | return true; | |||
507 | } | |||
508 | else | |||
509 | { | |||
510 | return false; | |||
511 | } | |||
512 | } | |||
513 | ||||
514 | return true; | |||
515 | } | |||
516 | ||||
517 | ||||
518 | bool | |||
519 | ClangASTImporter::RequireCompleteType (clang::QualType type) | |||
520 | { | |||
521 | if (type.isNull()) | |||
522 | return false; | |||
523 | ||||
524 | if (const TagType *tag_type = type->getAs<TagType>()) | |||
525 | { | |||
526 | TagDecl *tag_decl = tag_type->getDecl(); | |||
527 | ||||
528 | if (tag_decl->getDefinition() || tag_decl->isBeingDefined()) | |||
529 | return true; | |||
530 | ||||
531 | return CompleteTagDecl(tag_decl); | |||
532 | } | |||
533 | if (const ObjCObjectType *objc_object_type = type->getAs<ObjCObjectType>()) | |||
534 | { | |||
535 | if (ObjCInterfaceDecl *objc_interface_decl = objc_object_type->getInterface()) | |||
536 | return CompleteObjCInterfaceDecl(objc_interface_decl); | |||
537 | else | |||
538 | return false; | |||
539 | } | |||
540 | if (const ArrayType *array_type = type->getAsArrayTypeUnsafe()) | |||
541 | { | |||
542 | return RequireCompleteType(array_type->getElementType()); | |||
543 | } | |||
544 | if (const AtomicType *atomic_type = type->getAs<AtomicType>()) | |||
545 | { | |||
546 | return RequireCompleteType(atomic_type->getPointeeType()); | |||
547 | } | |||
548 | ||||
549 | return true; | |||
550 | } | |||
551 | ||||
552 | ClangASTMetadata * | |||
553 | ClangASTImporter::GetDeclMetadata (const clang::Decl *decl) | |||
554 | { | |||
555 | DeclOrigin decl_origin = GetDeclOrigin(decl); | |||
556 | ||||
557 | if (decl_origin.Valid()) | |||
558 | return ClangASTContext::GetMetadata(decl_origin.ctx, decl_origin.decl); | |||
559 | else | |||
560 | return ClangASTContext::GetMetadata(&decl->getASTContext(), decl); | |||
561 | } | |||
562 | ||||
563 | ClangASTImporter::DeclOrigin | |||
564 | ClangASTImporter::GetDeclOrigin(const clang::Decl *decl) | |||
565 | { | |||
566 | ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext()); | |||
567 | ||||
568 | OriginMap &origins = context_md->m_origins; | |||
569 | ||||
570 | OriginMap::iterator iter = origins.find(decl); | |||
571 | ||||
572 | if (iter != origins.end()) | |||
573 | return iter->second; | |||
574 | else | |||
575 | return DeclOrigin(); | |||
576 | } | |||
577 | ||||
578 | void | |||
579 | ClangASTImporter::SetDeclOrigin (const clang::Decl *decl, clang::Decl *original_decl) | |||
580 | { | |||
581 | ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext()); | |||
582 | ||||
583 | OriginMap &origins = context_md->m_origins; | |||
584 | ||||
585 | OriginMap::iterator iter = origins.find(decl); | |||
586 | ||||
587 | if (iter != origins.end()) | |||
588 | { | |||
589 | iter->second.decl = original_decl; | |||
590 | iter->second.ctx = &original_decl->getASTContext(); | |||
591 | } | |||
592 | else | |||
593 | { | |||
594 | origins[decl] = DeclOrigin(&original_decl->getASTContext(), original_decl); | |||
595 | } | |||
596 | } | |||
597 | ||||
598 | void | |||
599 | ClangASTImporter::RegisterNamespaceMap(const clang::NamespaceDecl *decl, | |||
600 | NamespaceMapSP &namespace_map) | |||
601 | { | |||
602 | ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext()); | |||
603 | ||||
604 | context_md->m_namespace_maps[decl] = namespace_map; | |||
605 | } | |||
606 | ||||
607 | ClangASTImporter::NamespaceMapSP | |||
608 | ClangASTImporter::GetNamespaceMap(const clang::NamespaceDecl *decl) | |||
609 | { | |||
610 | ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext()); | |||
611 | ||||
612 | NamespaceMetaMap &namespace_maps = context_md->m_namespace_maps; | |||
613 | ||||
614 | NamespaceMetaMap::iterator iter = namespace_maps.find(decl); | |||
615 | ||||
616 | if (iter != namespace_maps.end()) | |||
617 | return iter->second; | |||
618 | else | |||
619 | return NamespaceMapSP(); | |||
620 | } | |||
621 | ||||
622 | void | |||
623 | ClangASTImporter::BuildNamespaceMap(const clang::NamespaceDecl *decl) | |||
624 | { | |||
625 | assert (decl)((decl) ? static_cast<void> (0) : __assert_fail ("decl" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn255820/tools/lldb/source/Symbol/ClangASTImporter.cpp" , 625, __PRETTY_FUNCTION__)); | |||
626 | ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext()); | |||
627 | ||||
628 | const DeclContext *parent_context = decl->getDeclContext(); | |||
629 | const NamespaceDecl *parent_namespace = dyn_cast<NamespaceDecl>(parent_context); | |||
630 | NamespaceMapSP parent_map; | |||
631 | ||||
632 | if (parent_namespace) | |||
633 | parent_map = GetNamespaceMap(parent_namespace); | |||
634 | ||||
635 | NamespaceMapSP new_map; | |||
636 | ||||
637 | new_map.reset(new NamespaceMap); | |||
638 | ||||
639 | if (context_md->m_map_completer) | |||
640 | { | |||
641 | std::string namespace_string = decl->getDeclName().getAsString(); | |||
642 | ||||
643 | context_md->m_map_completer->CompleteNamespaceMap (new_map, ConstString(namespace_string.c_str()), parent_map); | |||
644 | } | |||
645 | ||||
646 | context_md->m_namespace_maps[decl] = new_map; | |||
647 | } | |||
648 | ||||
649 | void | |||
650 | ClangASTImporter::ForgetDestination (clang::ASTContext *dst_ast) | |||
651 | { | |||
652 | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS(1u << 8))); | |||
653 | ||||
654 | if (log) | |||
655 | log->Printf(" [ClangASTImporter] Forgetting destination (ASTContext*)%p", | |||
656 | static_cast<void*>(dst_ast)); | |||
657 | ||||
658 | m_metadata_map.erase(dst_ast); | |||
659 | } | |||
660 | ||||
661 | void | |||
662 | ClangASTImporter::ForgetSource (clang::ASTContext *dst_ast, clang::ASTContext *src_ast) | |||
663 | { | |||
664 | ASTContextMetadataSP md = MaybeGetContextMetadata (dst_ast); | |||
665 | ||||
666 | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS(1u << 8))); | |||
667 | ||||
668 | if (log) | |||
669 | log->Printf(" [ClangASTImporter] Forgetting source->dest (ASTContext*)%p->(ASTContext*)%p", | |||
670 | static_cast<void*>(src_ast), static_cast<void*>(dst_ast)); | |||
671 | ||||
672 | if (!md) | |||
673 | return; | |||
674 | ||||
675 | md->m_minions.erase(src_ast); | |||
676 | ||||
677 | for (OriginMap::iterator iter = md->m_origins.begin(); | |||
678 | iter != md->m_origins.end(); | |||
679 | ) | |||
680 | { | |||
681 | if (iter->second.ctx == src_ast) | |||
682 | md->m_origins.erase(iter++); | |||
683 | else | |||
684 | ++iter; | |||
685 | } | |||
686 | } | |||
687 | ||||
688 | ClangASTImporter::MapCompleter::~MapCompleter () | |||
689 | { | |||
690 | return; | |||
691 | } | |||
692 | ||||
693 | void | |||
694 | ClangASTImporter::Minion::InitDeportWorkQueues (std::set<clang::NamedDecl *> *decls_to_deport, | |||
695 | std::set<clang::NamedDecl *> *decls_already_deported) | |||
696 | { | |||
697 | 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.8~svn255820/tools/lldb/source/Symbol/ClangASTImporter.cpp" , 697, __PRETTY_FUNCTION__)); | |||
698 | 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.8~svn255820/tools/lldb/source/Symbol/ClangASTImporter.cpp" , 698, __PRETTY_FUNCTION__)); | |||
699 | ||||
700 | m_decls_to_deport = decls_to_deport; | |||
701 | m_decls_already_deported = decls_already_deported; | |||
702 | } | |||
703 | ||||
704 | void | |||
705 | ClangASTImporter::Minion::ExecuteDeportWorkQueues () | |||
706 | { | |||
707 | 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.8~svn255820/tools/lldb/source/Symbol/ClangASTImporter.cpp" , 707, __PRETTY_FUNCTION__)); | |||
708 | 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.8~svn255820/tools/lldb/source/Symbol/ClangASTImporter.cpp" , 708, __PRETTY_FUNCTION__)); | |||
709 | ||||
710 | ASTContextMetadataSP to_context_md = m_master.GetContextMetadata(&getToContext()); | |||
711 | ||||
712 | while (!m_decls_to_deport->empty()) | |||
713 | { | |||
714 | NamedDecl *decl = *m_decls_to_deport->begin(); | |||
715 | ||||
716 | m_decls_already_deported->insert(decl); | |||
717 | m_decls_to_deport->erase(decl); | |||
718 | ||||
719 | DeclOrigin &origin = to_context_md->m_origins[decl]; | |||
720 | UNUSED_IF_ASSERT_DISABLED(origin)((void)(origin)); | |||
721 | ||||
722 | 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.8~svn255820/tools/lldb/source/Symbol/ClangASTImporter.cpp" , 722, __PRETTY_FUNCTION__)); // otherwise we should never have added this | |||
723 | // because it doesn't need to be deported | |||
724 | ||||
725 | Decl *original_decl = to_context_md->m_origins[decl].decl; | |||
726 | ||||
727 | ClangASTContext::GetCompleteDecl (m_source_ctx, original_decl); | |||
728 | ||||
729 | if (TagDecl *tag_decl = dyn_cast<TagDecl>(decl)) | |||
730 | { | |||
731 | if (TagDecl *original_tag_decl = dyn_cast<TagDecl>(original_decl)) | |||
732 | if (original_tag_decl->isCompleteDefinition()) | |||
733 | ImportDefinitionTo(tag_decl, original_tag_decl); | |||
734 | ||||
735 | tag_decl->setHasExternalLexicalStorage(false); | |||
736 | tag_decl->setHasExternalVisibleStorage(false); | |||
737 | } | |||
738 | else if (ObjCInterfaceDecl *interface_decl = dyn_cast<ObjCInterfaceDecl>(decl)) | |||
739 | { | |||
740 | interface_decl->setHasExternalLexicalStorage(false); | |||
741 | interface_decl->setHasExternalVisibleStorage(false); | |||
742 | } | |||
743 | ||||
744 | to_context_md->m_origins.erase(decl); | |||
745 | } | |||
746 | ||||
747 | m_decls_to_deport = nullptr; | |||
748 | m_decls_already_deported = nullptr; | |||
749 | } | |||
750 | ||||
751 | void | |||
752 | ClangASTImporter::Minion::ImportDefinitionTo (clang::Decl *to, clang::Decl *from) | |||
753 | { | |||
754 | ASTImporter::Imported(from, to); | |||
755 | ||||
756 | ObjCInterfaceDecl *to_objc_interface = dyn_cast<ObjCInterfaceDecl>(to); | |||
757 | ||||
758 | /* | |||
759 | if (to_objc_interface) | |||
760 | to_objc_interface->startDefinition(); | |||
761 | ||||
762 | CXXRecordDecl *to_cxx_record = dyn_cast<CXXRecordDecl>(to); | |||
763 | ||||
764 | if (to_cxx_record) | |||
765 | to_cxx_record->startDefinition(); | |||
766 | */ | |||
767 | ||||
768 | ImportDefinition(from); | |||
769 | ||||
770 | // If we're dealing with an Objective-C class, ensure that the inheritance has | |||
771 | // been set up correctly. The ASTImporter may not do this correctly if the | |||
772 | // class was originally sourced from symbols. | |||
773 | ||||
774 | if (to_objc_interface) | |||
775 | { | |||
776 | do | |||
777 | { | |||
778 | ObjCInterfaceDecl *to_superclass = to_objc_interface->getSuperClass(); | |||
779 | ||||
780 | if (to_superclass) | |||
781 | break; // we're not going to override it if it's set | |||
782 | ||||
783 | ObjCInterfaceDecl *from_objc_interface = dyn_cast<ObjCInterfaceDecl>(from); | |||
784 | ||||
785 | if (!from_objc_interface) | |||
786 | break; | |||
787 | ||||
788 | ObjCInterfaceDecl *from_superclass = from_objc_interface->getSuperClass(); | |||
789 | ||||
790 | if (!from_superclass) | |||
791 | break; | |||
792 | ||||
793 | Decl *imported_from_superclass_decl = Import(from_superclass); | |||
794 | ||||
795 | if (!imported_from_superclass_decl) | |||
796 | break; | |||
797 | ||||
798 | ObjCInterfaceDecl *imported_from_superclass = dyn_cast<ObjCInterfaceDecl>(imported_from_superclass_decl); | |||
799 | ||||
800 | if (!imported_from_superclass) | |||
801 | break; | |||
802 | ||||
803 | if (!to_objc_interface->hasDefinition()) | |||
804 | to_objc_interface->startDefinition(); | |||
805 | ||||
806 | to_objc_interface->setSuperClass( | |||
807 | m_source_ctx->getTrivialTypeSourceInfo(m_source_ctx->getObjCInterfaceType(imported_from_superclass))); | |||
808 | } | |||
809 | while (0); | |||
810 | } | |||
811 | } | |||
812 | ||||
813 | clang::Decl * | |||
814 | ClangASTImporter::Minion::Imported (clang::Decl *from, clang::Decl *to) | |||
815 | { | |||
816 | ClangASTMetrics::RegisterClangImport(); | |||
817 | ||||
818 | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS(1u << 8))); | |||
819 | ||||
820 | lldb::user_id_t user_id = LLDB_INVALID_UID(18446744073709551615UL); | |||
821 | ClangASTMetadata *metadata = m_master.GetDeclMetadata(from); | |||
822 | if (metadata) | |||
823 | user_id = metadata->GetUserID(); | |||
824 | ||||
825 | if (log) | |||
826 | { | |||
827 | if (NamedDecl *from_named_decl = dyn_cast<clang::NamedDecl>(from)) | |||
828 | { | |||
829 | std::string name_string; | |||
830 | llvm::raw_string_ostream name_stream(name_string); | |||
831 | from_named_decl->printName(name_stream); | |||
832 | name_stream.flush(); | |||
833 | ||||
834 | log->Printf(" [ClangASTImporter] Imported (%sDecl*)%p, named %s (from (Decl*)%p), metadata 0x%" PRIx64"l" "x", | |||
835 | from->getDeclKindName(), static_cast<void*>(to), | |||
836 | name_string.c_str(), static_cast<void*>(from), | |||
837 | user_id); | |||
838 | } | |||
839 | else | |||
840 | { | |||
841 | log->Printf(" [ClangASTImporter] Imported (%sDecl*)%p (from (Decl*)%p), metadata 0x%" PRIx64"l" "x", | |||
842 | from->getDeclKindName(), static_cast<void*>(to), | |||
843 | static_cast<void*>(from), user_id); | |||
844 | } | |||
845 | } | |||
846 | ||||
847 | ASTContextMetadataSP to_context_md = m_master.GetContextMetadata(&to->getASTContext()); | |||
848 | ASTContextMetadataSP from_context_md = m_master.MaybeGetContextMetadata(m_source_ctx); | |||
849 | ||||
850 | if (from_context_md) | |||
851 | { | |||
852 | OriginMap &origins = from_context_md->m_origins; | |||
853 | ||||
854 | OriginMap::iterator origin_iter = origins.find(from); | |||
855 | ||||
856 | if (origin_iter != origins.end()) | |||
857 | { | |||
858 | if (to_context_md->m_origins.find(to) == to_context_md->m_origins.end() || | |||
859 | user_id != LLDB_INVALID_UID(18446744073709551615UL)) | |||
860 | { | |||
861 | if (origin_iter->second.ctx != &to->getASTContext()) | |||
862 | to_context_md->m_origins[to] = origin_iter->second; | |||
863 | } | |||
864 | ||||
865 | MinionSP direct_completer = m_master.GetMinion(&to->getASTContext(), origin_iter->second.ctx); | |||
866 | ||||
867 | if (direct_completer.get() != this) | |||
868 | direct_completer->ASTImporter::Imported(origin_iter->second.decl, to); | |||
869 | ||||
870 | if (log) | |||
871 | log->Printf(" [ClangASTImporter] Propagated origin (Decl*)%p/(ASTContext*)%p from (ASTContext*)%p to (ASTContext*)%p", | |||
872 | static_cast<void*>(origin_iter->second.decl), | |||
873 | static_cast<void*>(origin_iter->second.ctx), | |||
874 | static_cast<void*>(&from->getASTContext()), | |||
875 | static_cast<void*>(&to->getASTContext())); | |||
876 | } | |||
877 | else | |||
878 | { | |||
879 | if (m_decls_to_deport && m_decls_already_deported) | |||
880 | { | |||
881 | if (isa<TagDecl>(to) || isa<ObjCInterfaceDecl>(to)) | |||
882 | { | |||
883 | RecordDecl *from_record_decl = dyn_cast<RecordDecl>(from); | |||
884 | if (from_record_decl == nullptr || from_record_decl->isInjectedClassName() == false) | |||
885 | { | |||
886 | NamedDecl *to_named_decl = dyn_cast<NamedDecl>(to); | |||
887 | ||||
888 | if (!m_decls_already_deported->count(to_named_decl)) | |||
889 | m_decls_to_deport->insert(to_named_decl); | |||
890 | } | |||
891 | } | |||
892 | } | |||
893 | ||||
894 | if (to_context_md->m_origins.find(to) == to_context_md->m_origins.end() || | |||
895 | user_id != LLDB_INVALID_UID(18446744073709551615UL)) | |||
896 | { | |||
897 | to_context_md->m_origins[to] = DeclOrigin(m_source_ctx, from); | |||
898 | } | |||
899 | ||||
900 | if (log) | |||
901 | log->Printf(" [ClangASTImporter] Decl has no origin information in (ASTContext*)%p", | |||
902 | static_cast<void*>(&from->getASTContext())); | |||
903 | } | |||
904 | ||||
905 | if (clang::NamespaceDecl *to_namespace = dyn_cast<clang::NamespaceDecl>(to)) | |||
906 | { | |||
907 | clang::NamespaceDecl *from_namespace = dyn_cast<clang::NamespaceDecl>(from); | |||
908 | ||||
909 | NamespaceMetaMap &namespace_maps = from_context_md->m_namespace_maps; | |||
910 | ||||
911 | NamespaceMetaMap::iterator namespace_map_iter = namespace_maps.find(from_namespace); | |||
912 | ||||
913 | if (namespace_map_iter != namespace_maps.end()) | |||
914 | to_context_md->m_namespace_maps[to_namespace] = namespace_map_iter->second; | |||
915 | } | |||
916 | } | |||
917 | else | |||
918 | { | |||
919 | to_context_md->m_origins[to] = DeclOrigin (m_source_ctx, from); | |||
920 | ||||
921 | if (log) | |||
922 | log->Printf(" [ClangASTImporter] Sourced origin (Decl*)%p/(ASTContext*)%p into (ASTContext*)%p", | |||
923 | static_cast<void*>(from), | |||
924 | static_cast<void*>(m_source_ctx), | |||
925 | static_cast<void*>(&to->getASTContext())); | |||
926 | } | |||
927 | ||||
928 | if (TagDecl *from_tag_decl = dyn_cast<TagDecl>(from)) | |||
929 | { | |||
930 | TagDecl *to_tag_decl = dyn_cast<TagDecl>(to); | |||
931 | ||||
932 | to_tag_decl->setHasExternalLexicalStorage(); | |||
933 | to_tag_decl->setMustBuildLookupTable(); | |||
934 | ||||
935 | if (log) | |||
936 | log->Printf(" [ClangASTImporter] To is a TagDecl - attributes %s%s [%s->%s]", | |||
937 | (to_tag_decl->hasExternalLexicalStorage() ? " Lexical" : ""), | |||
938 | (to_tag_decl->hasExternalVisibleStorage() ? " Visible" : ""), | |||
939 | (from_tag_decl->isCompleteDefinition() ? "complete" : "incomplete"), | |||
940 | (to_tag_decl->isCompleteDefinition() ? "complete" : "incomplete")); | |||
941 | } | |||
942 | ||||
943 | if (isa<NamespaceDecl>(from)) | |||
944 | { | |||
945 | NamespaceDecl *to_namespace_decl = dyn_cast<NamespaceDecl>(to); | |||
946 | ||||
947 | m_master.BuildNamespaceMap(to_namespace_decl); | |||
948 | ||||
949 | to_namespace_decl->setHasExternalVisibleStorage(); | |||
950 | } | |||
951 | ||||
952 | if (isa<ObjCInterfaceDecl>(from)) | |||
953 | { | |||
954 | ObjCInterfaceDecl *to_interface_decl = dyn_cast<ObjCInterfaceDecl>(to); | |||
955 | ||||
956 | to_interface_decl->setHasExternalLexicalStorage(); | |||
957 | to_interface_decl->setHasExternalVisibleStorage(); | |||
958 | ||||
959 | /*to_interface_decl->setExternallyCompleted();*/ | |||
960 | ||||
961 | if (log) | |||
962 | log->Printf(" [ClangASTImporter] To is an ObjCInterfaceDecl - attributes %s%s%s", | |||
963 | (to_interface_decl->hasExternalLexicalStorage() ? " Lexical" : ""), | |||
964 | (to_interface_decl->hasExternalVisibleStorage() ? " Visible" : ""), | |||
965 | (to_interface_decl->hasDefinition() ? " HasDefinition" : "")); | |||
966 | } | |||
967 | ||||
968 | return clang::ASTImporter::Imported(from, to); | |||
969 | } | |||
970 | ||||
971 | clang::Decl *ClangASTImporter::Minion::GetOriginalDecl (clang::Decl *To) | |||
972 | { | |||
973 | ASTContextMetadataSP to_context_md = m_master.GetContextMetadata(&To->getASTContext()); | |||
974 | ||||
975 | if (!to_context_md) | |||
976 | return nullptr; | |||
977 | ||||
978 | OriginMap::iterator iter = to_context_md->m_origins.find(To); | |||
979 | ||||
980 | if (iter == to_context_md->m_origins.end()) | |||
981 | return nullptr; | |||
982 | ||||
983 | return const_cast<clang::Decl*>(iter->second.decl); | |||
984 | } |