]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Symbol/ClangASTImporter.cpp
Update LLDB snapshot to upstream r241361
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Symbol / ClangASTImporter.cpp
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, counters.m_visible_query_count);
30     log->Printf("  Number of lexical Decl queries             : %" PRIu64, counters.m_lexical_query_count);
31     log->Printf("  Number of imports initiated by LLDB        : %" PRIu64, counters.m_lldb_import_count);
32     log->Printf("  Number of imports conducted by Clang       : %" PRIu64, counters.m_clang_import_count);
33     log->Printf("  Number of Decls completed                  : %" PRIu64, counters.m_decls_completed_count);
34     log->Printf("  Number of records laid out                 : %" PRIu64, 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));
86
87             if (log)
88             {
89                 lldb::user_id_t user_id = LLDB_INVALID_UID;
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,
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,
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));
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));
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");
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     if (ObjCInterfaceDecl *super_class = interface_decl->getSuperClass())
279         RequireCompleteType(clang::QualType(super_class->getTypeForDecl(), 0));
280
281     return true;
282 }
283
284 bool
285 ClangASTImporter::RequireCompleteType (clang::QualType type)
286 {
287     if (type.isNull())
288         return false;
289     
290     if (const TagType *tag_type = type->getAs<TagType>())
291     {
292         TagDecl *tag_decl = tag_type->getDecl();
293
294         if (tag_decl->getDefinition() || tag_decl->isBeingDefined())
295             return true;
296
297         return CompleteTagDecl(tag_decl);
298     }
299     if (const ObjCObjectType *objc_object_type = type->getAs<ObjCObjectType>())
300     {
301         if (ObjCInterfaceDecl *objc_interface_decl = objc_object_type->getInterface())
302             return CompleteObjCInterfaceDecl(objc_interface_decl);
303         else
304             return false;
305     }
306     if (const ArrayType *array_type = type->getAsArrayTypeUnsafe())
307     {
308         return RequireCompleteType(array_type->getElementType());
309     }
310     if (const AtomicType *atomic_type = type->getAs<AtomicType>())
311     {
312         return RequireCompleteType(atomic_type->getPointeeType());
313     }
314     
315     return true;
316 }
317
318 ClangASTMetadata *
319 ClangASTImporter::GetDeclMetadata (const clang::Decl *decl)
320 {
321     DeclOrigin decl_origin = GetDeclOrigin(decl);
322     
323     if (decl_origin.Valid())
324         return ClangASTContext::GetMetadata(decl_origin.ctx, decl_origin.decl);
325     else
326         return ClangASTContext::GetMetadata(&decl->getASTContext(), decl);
327 }
328
329 ClangASTImporter::DeclOrigin
330 ClangASTImporter::GetDeclOrigin(const clang::Decl *decl)
331 {
332     ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
333     
334     OriginMap &origins = context_md->m_origins;
335     
336     OriginMap::iterator iter = origins.find(decl);
337     
338     if (iter != origins.end())
339         return iter->second;
340     else
341         return DeclOrigin();
342 }
343
344 void
345 ClangASTImporter::SetDeclOrigin (const clang::Decl *decl, clang::Decl *original_decl)
346 {
347     ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
348     
349     OriginMap &origins = context_md->m_origins;
350     
351     OriginMap::iterator iter = origins.find(decl);
352     
353     if (iter != origins.end())
354     {
355         iter->second.decl = original_decl;
356         iter->second.ctx = &original_decl->getASTContext();
357     }
358     else
359     {
360         origins[decl] = DeclOrigin(&original_decl->getASTContext(), original_decl);
361     }
362 }
363
364 void
365 ClangASTImporter::RegisterNamespaceMap(const clang::NamespaceDecl *decl, 
366                                        NamespaceMapSP &namespace_map)
367 {
368     ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
369     
370     context_md->m_namespace_maps[decl] = namespace_map;
371 }
372
373 ClangASTImporter::NamespaceMapSP 
374 ClangASTImporter::GetNamespaceMap(const clang::NamespaceDecl *decl)
375 {
376     ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
377
378     NamespaceMetaMap &namespace_maps = context_md->m_namespace_maps;
379     
380     NamespaceMetaMap::iterator iter = namespace_maps.find(decl);
381     
382     if (iter != namespace_maps.end())
383         return iter->second;
384     else
385         return NamespaceMapSP();
386 }
387
388 void 
389 ClangASTImporter::BuildNamespaceMap(const clang::NamespaceDecl *decl)
390 {
391     assert (decl);
392     ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
393
394     const DeclContext *parent_context = decl->getDeclContext();
395     const NamespaceDecl *parent_namespace = dyn_cast<NamespaceDecl>(parent_context);
396     NamespaceMapSP parent_map;
397     
398     if (parent_namespace)
399         parent_map = GetNamespaceMap(parent_namespace);
400     
401     NamespaceMapSP new_map;
402     
403     new_map.reset(new NamespaceMap);
404  
405     if (context_md->m_map_completer)
406     {
407         std::string namespace_string = decl->getDeclName().getAsString();
408     
409         context_md->m_map_completer->CompleteNamespaceMap (new_map, ConstString(namespace_string.c_str()), parent_map);
410     }
411     
412     context_md->m_namespace_maps[decl] = new_map;
413 }
414
415 void 
416 ClangASTImporter::ForgetDestination (clang::ASTContext *dst_ast)
417 {
418     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
419
420     if (log)
421         log->Printf("    [ClangASTImporter] Forgetting destination (ASTContext*)%p",
422                     static_cast<void*>(dst_ast));
423
424     m_metadata_map.erase(dst_ast);
425 }
426
427 void
428 ClangASTImporter::ForgetSource (clang::ASTContext *dst_ast, clang::ASTContext *src_ast)
429 {
430     ASTContextMetadataSP md = MaybeGetContextMetadata (dst_ast);
431
432     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
433
434     if (log)
435         log->Printf("    [ClangASTImporter] Forgetting source->dest (ASTContext*)%p->(ASTContext*)%p",
436                     static_cast<void*>(src_ast), static_cast<void*>(dst_ast));
437
438     if (!md)
439         return;
440
441     md->m_minions.erase(src_ast);
442
443     for (OriginMap::iterator iter = md->m_origins.begin();
444          iter != md->m_origins.end();
445          )
446     {
447         if (iter->second.ctx == src_ast)
448             md->m_origins.erase(iter++);
449         else
450             ++iter;
451     }
452 }
453
454 ClangASTImporter::MapCompleter::~MapCompleter ()
455 {
456     return;
457 }
458
459 void
460 ClangASTImporter::Minion::InitDeportWorkQueues (std::set<clang::NamedDecl *> *decls_to_deport,
461                                                 std::set<clang::NamedDecl *> *decls_already_deported)
462 {
463     assert(!m_decls_to_deport); // TODO make debug only
464     assert(!m_decls_already_deported);
465     
466     m_decls_to_deport = decls_to_deport;
467     m_decls_already_deported = decls_already_deported;
468 }
469
470 void
471 ClangASTImporter::Minion::ExecuteDeportWorkQueues ()
472 {
473     assert(m_decls_to_deport); // TODO make debug only
474     assert(m_decls_already_deported);
475     
476     ASTContextMetadataSP to_context_md = m_master.GetContextMetadata(&getToContext());
477         
478     while (!m_decls_to_deport->empty())
479     {
480         NamedDecl *decl = *m_decls_to_deport->begin();
481         
482         m_decls_already_deported->insert(decl);
483         m_decls_to_deport->erase(decl);
484         
485         DeclOrigin &origin = to_context_md->m_origins[decl];
486         
487         assert (origin.ctx == m_source_ctx);    // otherwise we should never have added this
488                                                 // because it doesn't need to be deported
489         
490         Decl *original_decl = to_context_md->m_origins[decl].decl;
491         
492         ClangASTContext::GetCompleteDecl (m_source_ctx, original_decl);
493         
494         if (TagDecl *tag_decl = dyn_cast<TagDecl>(decl))
495         {
496             if (TagDecl *original_tag_decl = dyn_cast<TagDecl>(original_decl))
497                 if (original_tag_decl->isCompleteDefinition())
498                     ImportDefinitionTo(tag_decl, original_tag_decl);
499             
500             tag_decl->setHasExternalLexicalStorage(false);
501             tag_decl->setHasExternalVisibleStorage(false);
502         }
503         else if (ObjCInterfaceDecl *interface_decl = dyn_cast<ObjCInterfaceDecl>(decl))
504         {
505             interface_decl->setHasExternalLexicalStorage(false);
506             interface_decl->setHasExternalVisibleStorage(false);
507         }
508         
509         to_context_md->m_origins.erase(decl);
510     }
511     
512     m_decls_to_deport = nullptr;
513     m_decls_already_deported = nullptr;
514 }
515
516 void
517 ClangASTImporter::Minion::ImportDefinitionTo (clang::Decl *to, clang::Decl *from)
518 {
519     ASTImporter::Imported(from, to);
520
521     ObjCInterfaceDecl *to_objc_interface = dyn_cast<ObjCInterfaceDecl>(to);
522
523     /*
524     if (to_objc_interface)
525         to_objc_interface->startDefinition();
526  
527     CXXRecordDecl *to_cxx_record = dyn_cast<CXXRecordDecl>(to);
528     
529     if (to_cxx_record)
530         to_cxx_record->startDefinition();
531     */
532
533     ImportDefinition(from);
534      
535     // If we're dealing with an Objective-C class, ensure that the inheritance has
536     // been set up correctly.  The ASTImporter may not do this correctly if the 
537     // class was originally sourced from symbols.
538     
539     if (to_objc_interface)
540     {
541         do
542         {
543             ObjCInterfaceDecl *to_superclass = to_objc_interface->getSuperClass();
544
545             if (to_superclass)
546                 break; // we're not going to override it if it's set
547             
548             ObjCInterfaceDecl *from_objc_interface = dyn_cast<ObjCInterfaceDecl>(from);
549             
550             if (!from_objc_interface)
551                 break;
552             
553             ObjCInterfaceDecl *from_superclass = from_objc_interface->getSuperClass();
554             
555             if (!from_superclass)
556                 break;
557             
558             Decl *imported_from_superclass_decl = Import(from_superclass);
559                 
560             if (!imported_from_superclass_decl)
561                 break;
562                 
563             ObjCInterfaceDecl *imported_from_superclass = dyn_cast<ObjCInterfaceDecl>(imported_from_superclass_decl);
564             
565             if (!imported_from_superclass)
566                 break;
567             
568             if (!to_objc_interface->hasDefinition())
569                 to_objc_interface->startDefinition();
570             
571             to_objc_interface->setSuperClass(imported_from_superclass);
572         }
573         while (0);
574     }
575 }
576
577 clang::Decl *
578 ClangASTImporter::Minion::Imported (clang::Decl *from, clang::Decl *to)
579 {
580     ClangASTMetrics::RegisterClangImport();
581
582     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
583
584     lldb::user_id_t user_id = LLDB_INVALID_UID;
585     ClangASTMetadata *metadata = m_master.GetDeclMetadata(from);
586     if (metadata)
587         user_id = metadata->GetUserID();
588     
589     if (log)
590     {
591         if (NamedDecl *from_named_decl = dyn_cast<clang::NamedDecl>(from))
592         {
593             std::string name_string;
594             llvm::raw_string_ostream name_stream(name_string);
595             from_named_decl->printName(name_stream);
596             name_stream.flush();
597
598             log->Printf("    [ClangASTImporter] Imported (%sDecl*)%p, named %s (from (Decl*)%p), metadata 0x%" PRIx64,
599                         from->getDeclKindName(), static_cast<void*>(to),
600                         name_string.c_str(), static_cast<void*>(from),
601                         user_id);
602         }
603         else
604         {
605             log->Printf("    [ClangASTImporter] Imported (%sDecl*)%p (from (Decl*)%p), metadata 0x%" PRIx64,
606                         from->getDeclKindName(), static_cast<void*>(to),
607                         static_cast<void*>(from), user_id);
608         }
609     }
610
611     ASTContextMetadataSP to_context_md = m_master.GetContextMetadata(&to->getASTContext());
612     ASTContextMetadataSP from_context_md = m_master.MaybeGetContextMetadata(m_source_ctx);
613
614     if (from_context_md)
615     {
616         OriginMap &origins = from_context_md->m_origins;
617
618         OriginMap::iterator origin_iter = origins.find(from);
619
620         if (origin_iter != origins.end())
621         {
622             if (to_context_md->m_origins.find(to) == to_context_md->m_origins.end() ||
623                 user_id != LLDB_INVALID_UID)
624             {
625                 to_context_md->m_origins[to] = origin_iter->second;
626             }
627                 
628             MinionSP direct_completer = m_master.GetMinion(&to->getASTContext(), origin_iter->second.ctx);
629
630             if (direct_completer.get() != this)
631                 direct_completer->ASTImporter::Imported(origin_iter->second.decl, to);
632
633             if (log)
634                 log->Printf("    [ClangASTImporter] Propagated origin (Decl*)%p/(ASTContext*)%p from (ASTContext*)%p to (ASTContext*)%p",
635                             static_cast<void*>(origin_iter->second.decl),
636                             static_cast<void*>(origin_iter->second.ctx),
637                             static_cast<void*>(&from->getASTContext()),
638                             static_cast<void*>(&to->getASTContext()));
639         }
640         else
641         {
642             if (m_decls_to_deport && m_decls_already_deported)
643             {
644                 if (isa<TagDecl>(to) || isa<ObjCInterfaceDecl>(to))
645                 {
646                     NamedDecl *to_named_decl = dyn_cast<NamedDecl>(to);
647
648                     if (!m_decls_already_deported->count(to_named_decl))
649                         m_decls_to_deport->insert(to_named_decl);
650                 }
651             }
652             
653             if (to_context_md->m_origins.find(to) == to_context_md->m_origins.end() ||
654                 user_id != LLDB_INVALID_UID)
655             {
656                 to_context_md->m_origins[to] = DeclOrigin(m_source_ctx, from);
657             }
658
659             if (log)
660                 log->Printf("    [ClangASTImporter] Decl has no origin information in (ASTContext*)%p",
661                             static_cast<void*>(&from->getASTContext()));
662         }
663
664         if (clang::NamespaceDecl *to_namespace = dyn_cast<clang::NamespaceDecl>(to))
665         {
666             clang::NamespaceDecl *from_namespace = dyn_cast<clang::NamespaceDecl>(from);
667
668             NamespaceMetaMap &namespace_maps = from_context_md->m_namespace_maps;
669
670             NamespaceMetaMap::iterator namespace_map_iter = namespace_maps.find(from_namespace);
671
672             if (namespace_map_iter != namespace_maps.end())
673                 to_context_md->m_namespace_maps[to_namespace] = namespace_map_iter->second;
674         }
675     }
676     else
677     {
678         to_context_md->m_origins[to] = DeclOrigin (m_source_ctx, from);
679
680         if (log)
681             log->Printf("    [ClangASTImporter] Sourced origin (Decl*)%p/(ASTContext*)%p into (ASTContext*)%p",
682                         static_cast<void*>(from),
683                         static_cast<void*>(m_source_ctx),
684                         static_cast<void*>(&to->getASTContext()));
685     }
686
687     if (TagDecl *from_tag_decl = dyn_cast<TagDecl>(from))
688     {
689         TagDecl *to_tag_decl = dyn_cast<TagDecl>(to);
690
691         to_tag_decl->setHasExternalLexicalStorage();
692         to_tag_decl->setMustBuildLookupTable();
693
694         if (log)
695             log->Printf("    [ClangASTImporter] To is a TagDecl - attributes %s%s [%s->%s]",
696                         (to_tag_decl->hasExternalLexicalStorage() ? " Lexical" : ""),
697                         (to_tag_decl->hasExternalVisibleStorage() ? " Visible" : ""),
698                         (from_tag_decl->isCompleteDefinition() ? "complete" : "incomplete"),
699                         (to_tag_decl->isCompleteDefinition() ? "complete" : "incomplete"));
700     }
701
702     if (isa<NamespaceDecl>(from))
703     {
704         NamespaceDecl *to_namespace_decl = dyn_cast<NamespaceDecl>(to);
705
706         m_master.BuildNamespaceMap(to_namespace_decl);
707
708         to_namespace_decl->setHasExternalVisibleStorage();
709     }
710
711     if (isa<ObjCInterfaceDecl>(from))
712     {
713         ObjCInterfaceDecl *to_interface_decl = dyn_cast<ObjCInterfaceDecl>(to);
714
715         to_interface_decl->setHasExternalLexicalStorage();
716         to_interface_decl->setHasExternalVisibleStorage();
717
718         /*to_interface_decl->setExternallyCompleted();*/
719
720         if (log)
721             log->Printf("    [ClangASTImporter] To is an ObjCInterfaceDecl - attributes %s%s%s",
722                         (to_interface_decl->hasExternalLexicalStorage() ? " Lexical" : ""),
723                         (to_interface_decl->hasExternalVisibleStorage() ? " Visible" : ""),
724                         (to_interface_decl->hasDefinition() ? " HasDefinition" : ""));
725     }
726
727     return clang::ASTImporter::Imported(from, to);
728 }
729
730 clang::Decl *ClangASTImporter::Minion::GetOriginalDecl (clang::Decl *To)
731 {
732     ASTContextMetadataSP to_context_md = m_master.GetContextMetadata(&To->getASTContext());
733     
734     if (!to_context_md)
735         return nullptr;
736     
737     OriginMap::iterator iter = to_context_md->m_origins.find(To);
738     
739     if (iter == to_context_md->m_origins.end())
740         return nullptr;
741     
742     return const_cast<clang::Decl*>(iter->second.decl);
743 }