• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
DumpCounters(Log * log,ClangASTMetrics::Counters & counters)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 
DumpCounters(Log * log)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
CopyType(clang::ASTContext * dst_ast,clang::ASTContext * src_ast,clang::QualType type)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
CopyType(clang::ASTContext * dst_ast,clang::ASTContext * src_ast,lldb::clang_type_t type)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 *
CopyDecl(clang::ASTContext * dst_ast,clang::ASTContext * src_ast,clang::Decl * 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;
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 NULL;
110 }
111 
112 lldb::clang_type_t
DeportType(clang::ASTContext * dst_ctx,clang::ASTContext * src_ctx,lldb::clang_type_t type)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 NULL;
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 NULL;
134 
135     return result;
136 
137 }
138 
139 clang::Decl *
DeportDecl(clang::ASTContext * dst_ctx,clang::ASTContext * src_ctx,clang::Decl * 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(),
149                     decl,
150                     src_ctx,
151                     dst_ctx);
152 
153     MinionSP minion_sp (GetMinion (dst_ctx, src_ctx));
154 
155     if (!minion_sp)
156         return NULL;
157 
158     std::set<NamedDecl *> decls_to_deport;
159     std::set<NamedDecl *> decls_already_deported;
160 
161     minion_sp->InitDeportWorkQueues(&decls_to_deport,
162                                     &decls_already_deported);
163 
164     clang::Decl *result = CopyDecl(dst_ctx, src_ctx, decl);
165 
166     minion_sp->ExecuteDeportWorkQueues();
167 
168     if (!result)
169         return NULL;
170 
171     if (log)
172         log->Printf("    [ClangASTImporter] DeportDecl deported (%sDecl*)%p to (%sDecl*)%p",
173                     decl->getDeclKindName(),
174                     decl,
175                     result->getDeclKindName(),
176                     result);
177 
178     return result;
179 }
180 
181 void
CompleteDecl(clang::Decl * decl)182 ClangASTImporter::CompleteDecl (clang::Decl *decl)
183 {
184     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
185 
186     if (log)
187         log->Printf("    [ClangASTImporter] CompleteDecl called on (%sDecl*)%p",
188                     decl->getDeclKindName(),
189                     decl);
190 
191     if (ObjCInterfaceDecl *interface_decl = dyn_cast<ObjCInterfaceDecl>(decl))
192     {
193         if (!interface_decl->getDefinition())
194         {
195             interface_decl->startDefinition();
196             CompleteObjCInterfaceDecl(interface_decl);
197         }
198     }
199     else if (ObjCProtocolDecl *protocol_decl = dyn_cast<ObjCProtocolDecl>(decl))
200     {
201         if (!protocol_decl->getDefinition())
202             protocol_decl->startDefinition();
203     }
204     else if (TagDecl *tag_decl = dyn_cast<TagDecl>(decl))
205     {
206         if (!tag_decl->getDefinition() && !tag_decl->isBeingDefined())
207         {
208             tag_decl->startDefinition();
209             CompleteTagDecl(tag_decl);
210             tag_decl->setCompleteDefinition(true);
211         }
212     }
213     else
214     {
215         assert (0 && "CompleteDecl called on a Decl that can't be completed");
216     }
217 }
218 
219 bool
CompleteTagDecl(clang::TagDecl * decl)220 ClangASTImporter::CompleteTagDecl (clang::TagDecl *decl)
221 {
222     ClangASTMetrics::RegisterDeclCompletion();
223 
224     DeclOrigin decl_origin = GetDeclOrigin(decl);
225 
226     if (!decl_origin.Valid())
227         return false;
228 
229     if (!ClangASTContext::GetCompleteDecl(decl_origin.ctx, decl_origin.decl))
230         return false;
231 
232     MinionSP minion_sp (GetMinion(&decl->getASTContext(), decl_origin.ctx));
233 
234     if (minion_sp)
235         minion_sp->ImportDefinitionTo(decl, decl_origin.decl);
236 
237     return true;
238 }
239 
240 bool
CompleteTagDeclWithOrigin(clang::TagDecl * decl,clang::TagDecl * origin_decl)241 ClangASTImporter::CompleteTagDeclWithOrigin(clang::TagDecl *decl, clang::TagDecl *origin_decl)
242 {
243     ClangASTMetrics::RegisterDeclCompletion();
244 
245     clang::ASTContext *origin_ast_ctx = &origin_decl->getASTContext();
246 
247     if (!ClangASTContext::GetCompleteDecl(origin_ast_ctx, origin_decl))
248         return false;
249 
250     MinionSP minion_sp (GetMinion(&decl->getASTContext(), origin_ast_ctx));
251 
252     if (minion_sp)
253         minion_sp->ImportDefinitionTo(decl, origin_decl);
254 
255     ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
256 
257     OriginMap &origins = context_md->m_origins;
258 
259     origins[decl] = DeclOrigin(origin_ast_ctx, origin_decl);
260 
261     return true;
262 }
263 
264 bool
CompleteObjCInterfaceDecl(clang::ObjCInterfaceDecl * interface_decl)265 ClangASTImporter::CompleteObjCInterfaceDecl (clang::ObjCInterfaceDecl *interface_decl)
266 {
267     ClangASTMetrics::RegisterDeclCompletion();
268 
269     DeclOrigin decl_origin = GetDeclOrigin(interface_decl);
270 
271     if (!decl_origin.Valid())
272         return false;
273 
274     if (!ClangASTContext::GetCompleteDecl(decl_origin.ctx, decl_origin.decl))
275         return false;
276 
277     MinionSP minion_sp (GetMinion(&interface_decl->getASTContext(), decl_origin.ctx));
278 
279     if (minion_sp)
280         minion_sp->ImportDefinitionTo(interface_decl, decl_origin.decl);
281 
282     return true;
283 }
284 
285 bool
RequireCompleteType(clang::QualType type)286 ClangASTImporter::RequireCompleteType (clang::QualType type)
287 {
288     if (type.isNull())
289         return false;
290 
291     if (const TagType *tag_type = type->getAs<TagType>())
292     {
293         return CompleteTagDecl(tag_type->getDecl());
294     }
295     if (const ObjCObjectType *objc_object_type = type->getAs<ObjCObjectType>())
296     {
297         if (ObjCInterfaceDecl *objc_interface_decl = objc_object_type->getInterface())
298             return CompleteObjCInterfaceDecl(objc_interface_decl);
299         else
300             return false;
301     }
302     if (const ArrayType *array_type = type->getAsArrayTypeUnsafe())
303     {
304         return RequireCompleteType(array_type->getElementType());
305     }
306     if (const AtomicType *atomic_type = type->getAs<AtomicType>())
307     {
308         return RequireCompleteType(atomic_type->getPointeeType());
309     }
310 
311     return true;
312 }
313 
314 ClangASTMetadata *
GetDeclMetadata(const clang::Decl * decl)315 ClangASTImporter::GetDeclMetadata (const clang::Decl *decl)
316 {
317     DeclOrigin decl_origin = GetDeclOrigin(decl);
318 
319     if (decl_origin.Valid())
320         return ClangASTContext::GetMetadata(decl_origin.ctx, decl_origin.decl);
321     else
322         return ClangASTContext::GetMetadata(&decl->getASTContext(), decl);
323 }
324 
325 ClangASTImporter::DeclOrigin
GetDeclOrigin(const clang::Decl * decl)326 ClangASTImporter::GetDeclOrigin(const clang::Decl *decl)
327 {
328     ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
329 
330     OriginMap &origins = context_md->m_origins;
331 
332     OriginMap::iterator iter = origins.find(decl);
333 
334     if (iter != origins.end())
335         return iter->second;
336     else
337         return DeclOrigin();
338 }
339 
340 void
SetDeclOrigin(const clang::Decl * decl,clang::Decl * original_decl)341 ClangASTImporter::SetDeclOrigin (const clang::Decl *decl, clang::Decl *original_decl)
342 {
343     ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
344 
345     OriginMap &origins = context_md->m_origins;
346 
347     OriginMap::iterator iter = origins.find(decl);
348 
349     if (iter != origins.end())
350     {
351         iter->second.decl = original_decl;
352         iter->second.ctx = &original_decl->getASTContext();
353     }
354     else
355     {
356         origins[decl] = DeclOrigin(&original_decl->getASTContext(), original_decl);
357     }
358 }
359 
360 void
RegisterNamespaceMap(const clang::NamespaceDecl * decl,NamespaceMapSP & namespace_map)361 ClangASTImporter::RegisterNamespaceMap(const clang::NamespaceDecl *decl,
362                                        NamespaceMapSP &namespace_map)
363 {
364     ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
365 
366     context_md->m_namespace_maps[decl] = namespace_map;
367 }
368 
369 ClangASTImporter::NamespaceMapSP
GetNamespaceMap(const clang::NamespaceDecl * decl)370 ClangASTImporter::GetNamespaceMap(const clang::NamespaceDecl *decl)
371 {
372     ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
373 
374     NamespaceMetaMap &namespace_maps = context_md->m_namespace_maps;
375 
376     NamespaceMetaMap::iterator iter = namespace_maps.find(decl);
377 
378     if (iter != namespace_maps.end())
379         return iter->second;
380     else
381         return NamespaceMapSP();
382 }
383 
384 void
BuildNamespaceMap(const clang::NamespaceDecl * decl)385 ClangASTImporter::BuildNamespaceMap(const clang::NamespaceDecl *decl)
386 {
387     assert (decl);
388     ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
389 
390     const DeclContext *parent_context = decl->getDeclContext();
391     const NamespaceDecl *parent_namespace = dyn_cast<NamespaceDecl>(parent_context);
392     NamespaceMapSP parent_map;
393 
394     if (parent_namespace)
395         parent_map = GetNamespaceMap(parent_namespace);
396 
397     NamespaceMapSP new_map;
398 
399     new_map.reset(new NamespaceMap);
400 
401     if (context_md->m_map_completer)
402     {
403         std::string namespace_string = decl->getDeclName().getAsString();
404 
405         context_md->m_map_completer->CompleteNamespaceMap (new_map, ConstString(namespace_string.c_str()), parent_map);
406     }
407 
408     context_md->m_namespace_maps[decl] = new_map;
409 }
410 
411 void
ForgetDestination(clang::ASTContext * dst_ast)412 ClangASTImporter::ForgetDestination (clang::ASTContext *dst_ast)
413 {
414     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
415 
416     if (log)
417         log->Printf("    [ClangASTImporter] Forgetting destination (ASTContext*)%p", dst_ast);
418 
419     m_metadata_map.erase(dst_ast);
420 }
421 
422 void
ForgetSource(clang::ASTContext * dst_ast,clang::ASTContext * src_ast)423 ClangASTImporter::ForgetSource (clang::ASTContext *dst_ast, clang::ASTContext *src_ast)
424 {
425     ASTContextMetadataSP md = MaybeGetContextMetadata (dst_ast);
426 
427     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
428 
429     if (log)
430         log->Printf("    [ClangASTImporter] Forgetting source->dest (ASTContext*)%p->(ASTContext*)%p", src_ast, dst_ast);
431 
432     if (!md)
433         return;
434 
435     md->m_minions.erase(src_ast);
436 
437     for (OriginMap::iterator iter = md->m_origins.begin();
438          iter != md->m_origins.end();
439          )
440     {
441         if (iter->second.ctx == src_ast)
442             md->m_origins.erase(iter++);
443         else
444             ++iter;
445     }
446 }
447 
~MapCompleter()448 ClangASTImporter::MapCompleter::~MapCompleter ()
449 {
450     return;
451 }
452 
453 void
InitDeportWorkQueues(std::set<clang::NamedDecl * > * decls_to_deport,std::set<clang::NamedDecl * > * decls_already_deported)454 ClangASTImporter::Minion::InitDeportWorkQueues (std::set<clang::NamedDecl *> *decls_to_deport,
455                                                 std::set<clang::NamedDecl *> *decls_already_deported)
456 {
457     assert(!m_decls_to_deport); // TODO make debug only
458     assert(!m_decls_already_deported);
459 
460     m_decls_to_deport = decls_to_deport;
461     m_decls_already_deported = decls_already_deported;
462 }
463 
464 void
ExecuteDeportWorkQueues()465 ClangASTImporter::Minion::ExecuteDeportWorkQueues ()
466 {
467     assert(m_decls_to_deport); // TODO make debug only
468     assert(m_decls_already_deported);
469 
470     ASTContextMetadataSP to_context_md = m_master.GetContextMetadata(&getToContext());
471 
472     while (!m_decls_to_deport->empty())
473     {
474         NamedDecl *decl = *m_decls_to_deport->begin();
475 
476         m_decls_already_deported->insert(decl);
477         m_decls_to_deport->erase(decl);
478 
479         DeclOrigin &origin = to_context_md->m_origins[decl];
480 
481         assert (origin.ctx == m_source_ctx);    // otherwise we should never have added this
482                                                 // because it doesn't need to be deported
483 
484         Decl *original_decl = to_context_md->m_origins[decl].decl;
485 
486         ClangASTContext::GetCompleteDecl (m_source_ctx, original_decl);
487 
488         if (TagDecl *tag_decl = dyn_cast<TagDecl>(decl))
489         {
490             if (TagDecl *original_tag_decl = dyn_cast<TagDecl>(original_decl))
491                 if (original_tag_decl->isCompleteDefinition())
492                     ImportDefinitionTo(tag_decl, original_tag_decl);
493 
494             tag_decl->setHasExternalLexicalStorage(false);
495             tag_decl->setHasExternalVisibleStorage(false);
496         }
497         else if (ObjCInterfaceDecl *interface_decl = dyn_cast<ObjCInterfaceDecl>(decl))
498         {
499             interface_decl->setHasExternalLexicalStorage(false);
500             interface_decl->setHasExternalVisibleStorage(false);
501         }
502 
503         to_context_md->m_origins.erase(decl);
504     }
505 
506     m_decls_to_deport = NULL;
507     m_decls_already_deported = NULL;
508 }
509 
510 void
ImportDefinitionTo(clang::Decl * to,clang::Decl * from)511 ClangASTImporter::Minion::ImportDefinitionTo (clang::Decl *to, clang::Decl *from)
512 {
513     ASTImporter::Imported(from, to);
514 
515     ObjCInterfaceDecl *to_objc_interface = dyn_cast<ObjCInterfaceDecl>(to);
516 
517     /*
518     if (to_objc_interface)
519         to_objc_interface->startDefinition();
520 
521     CXXRecordDecl *to_cxx_record = dyn_cast<CXXRecordDecl>(to);
522 
523     if (to_cxx_record)
524         to_cxx_record->startDefinition();
525     */
526 
527     ImportDefinition(from);
528 
529     // If we're dealing with an Objective-C class, ensure that the inheritance has
530     // been set up correctly.  The ASTImporter may not do this correctly if the
531     // class was originally sourced from symbols.
532 
533     if (to_objc_interface)
534     {
535         do
536         {
537             ObjCInterfaceDecl *to_superclass = to_objc_interface->getSuperClass();
538 
539             if (to_superclass)
540                 break; // we're not going to override it if it's set
541 
542             ObjCInterfaceDecl *from_objc_interface = dyn_cast<ObjCInterfaceDecl>(from);
543 
544             if (!from_objc_interface)
545                 break;
546 
547             ObjCInterfaceDecl *from_superclass = from_objc_interface->getSuperClass();
548 
549             if (!from_superclass)
550                 break;
551 
552             Decl *imported_from_superclass_decl = Import(from_superclass);
553 
554             if (!imported_from_superclass_decl)
555                 break;
556 
557             ObjCInterfaceDecl *imported_from_superclass = dyn_cast<ObjCInterfaceDecl>(imported_from_superclass_decl);
558 
559             if (!imported_from_superclass)
560                 break;
561 
562             if (!to_objc_interface->hasDefinition())
563                 to_objc_interface->startDefinition();
564 
565             to_objc_interface->setSuperClass(imported_from_superclass);
566         }
567         while (0);
568     }
569 }
570 
571 clang::Decl *
Imported(clang::Decl * from,clang::Decl * to)572 ClangASTImporter::Minion::Imported (clang::Decl *from, clang::Decl *to)
573 {
574     ClangASTMetrics::RegisterClangImport();
575 
576     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
577 
578     if (log)
579     {
580         lldb::user_id_t user_id;
581         ClangASTMetadata *metadata = m_master.GetDeclMetadata(from);
582         if (metadata)
583             user_id = metadata->GetUserID();
584 
585         if (NamedDecl *from_named_decl = dyn_cast<clang::NamedDecl>(from))
586         {
587             std::string name_string;
588             llvm::raw_string_ostream name_stream(name_string);
589             from_named_decl->printName(name_stream);
590             name_stream.flush();
591 
592             log->Printf("    [ClangASTImporter] Imported (%sDecl*)%p, named %s (from (Decl*)%p), metadata 0x%" PRIx64,
593                         from->getDeclKindName(),
594                         to,
595                         name_string.c_str(),
596                         from,
597                         user_id);
598         }
599         else
600         {
601             log->Printf("    [ClangASTImporter] Imported (%sDecl*)%p (from (Decl*)%p), metadata 0x%" PRIx64,
602                         from->getDeclKindName(),
603                         to,
604                         from,
605                         user_id);
606         }
607     }
608 
609     ASTContextMetadataSP to_context_md = m_master.GetContextMetadata(&to->getASTContext());
610     ASTContextMetadataSP from_context_md = m_master.MaybeGetContextMetadata(m_source_ctx);
611 
612     if (from_context_md)
613     {
614         OriginMap &origins = from_context_md->m_origins;
615 
616         OriginMap::iterator origin_iter = origins.find(from);
617 
618         if (origin_iter != origins.end())
619         {
620             to_context_md->m_origins[to] = origin_iter->second;
621 
622             MinionSP direct_completer = m_master.GetMinion(&to->getASTContext(), origin_iter->second.ctx);
623 
624             if (direct_completer.get() != this)
625                 direct_completer->ASTImporter::Imported(origin_iter->second.decl, to);
626 
627             if (log)
628                 log->Printf("    [ClangASTImporter] Propagated origin (Decl*)%p/(ASTContext*)%p from (ASTContext*)%p to (ASTContext*)%p",
629                             origin_iter->second.decl,
630                             origin_iter->second.ctx,
631                             &from->getASTContext(),
632                             &to->getASTContext());
633         }
634         else
635         {
636             if (m_decls_to_deport && m_decls_already_deported)
637             {
638                 if (isa<TagDecl>(to) || isa<ObjCInterfaceDecl>(to))
639                 {
640                     NamedDecl *to_named_decl = dyn_cast<NamedDecl>(to);
641 
642                     if (!m_decls_already_deported->count(to_named_decl))
643                         m_decls_to_deport->insert(to_named_decl);
644                 }
645 
646             }
647             to_context_md->m_origins[to] = DeclOrigin(m_source_ctx, from);
648 
649             if (log)
650                 log->Printf("    [ClangASTImporter] Decl has no origin information in (ASTContext*)%p",
651                             &from->getASTContext());
652         }
653 
654         if (clang::NamespaceDecl *to_namespace = dyn_cast<clang::NamespaceDecl>(to))
655         {
656             clang::NamespaceDecl *from_namespace = dyn_cast<clang::NamespaceDecl>(from);
657 
658             NamespaceMetaMap &namespace_maps = from_context_md->m_namespace_maps;
659 
660             NamespaceMetaMap::iterator namespace_map_iter = namespace_maps.find(from_namespace);
661 
662             if (namespace_map_iter != namespace_maps.end())
663                 to_context_md->m_namespace_maps[to_namespace] = namespace_map_iter->second;
664         }
665     }
666     else
667     {
668         to_context_md->m_origins[to] = DeclOrigin (m_source_ctx, from);
669 
670         if (log)
671             log->Printf("    [ClangASTImporter] Sourced origin (Decl*)%p/(ASTContext*)%p into (ASTContext*)%p",
672                         from,
673                         m_source_ctx,
674                         &to->getASTContext());
675     }
676 
677     if (TagDecl *from_tag_decl = dyn_cast<TagDecl>(from))
678     {
679         TagDecl *to_tag_decl = dyn_cast<TagDecl>(to);
680 
681         to_tag_decl->setHasExternalLexicalStorage();
682         to_tag_decl->setMustBuildLookupTable();
683 
684         if (log)
685             log->Printf("    [ClangASTImporter] To is a TagDecl - attributes %s%s [%s->%s]",
686                         (to_tag_decl->hasExternalLexicalStorage() ? " Lexical" : ""),
687                         (to_tag_decl->hasExternalVisibleStorage() ? " Visible" : ""),
688                         (from_tag_decl->isCompleteDefinition() ? "complete" : "incomplete"),
689                         (to_tag_decl->isCompleteDefinition() ? "complete" : "incomplete"));
690     }
691 
692     if (isa<NamespaceDecl>(from))
693     {
694         NamespaceDecl *to_namespace_decl = dyn_cast<NamespaceDecl>(to);
695 
696         m_master.BuildNamespaceMap(to_namespace_decl);
697 
698         to_namespace_decl->setHasExternalVisibleStorage();
699     }
700 
701     if (isa<ObjCInterfaceDecl>(from))
702     {
703         ObjCInterfaceDecl *to_interface_decl = dyn_cast<ObjCInterfaceDecl>(to);
704 
705         to_interface_decl->setHasExternalLexicalStorage();
706         to_interface_decl->setHasExternalVisibleStorage();
707 
708         /*to_interface_decl->setExternallyCompleted();*/
709 
710         if (log)
711             log->Printf("    [ClangASTImporter] To is an ObjCInterfaceDecl - attributes %s%s%s",
712                         (to_interface_decl->hasExternalLexicalStorage() ? " Lexical" : ""),
713                         (to_interface_decl->hasExternalVisibleStorage() ? " Visible" : ""),
714                         (to_interface_decl->hasDefinition() ? " HasDefinition" : ""));
715     }
716 
717     return clang::ASTImporter::Imported(from, to);
718 }
719