]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/llvm/tools/lldb/source/Symbol/ClangASTImporter.cpp
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.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;
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
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 *
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
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
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
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
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
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 *
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
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
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
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 
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 
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 
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
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
448 ClangASTImporter::MapCompleter::~MapCompleter ()
449 {
450     return;
451 }
452
453 void
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
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
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 *
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
720 clang::Decl *ClangASTImporter::Minion::GetOriginalDecl (clang::Decl *To)
721 {
722     ASTContextMetadataSP to_context_md = m_master.GetContextMetadata(&To->getASTContext());
723     
724     if (!to_context_md)
725         return NULL;
726     
727     OriginMap::iterator iter = to_context_md->m_origins.find(To);
728     
729     if (iter == to_context_md->m_origins.end())
730         return NULL;
731     
732     return const_cast<clang::Decl*>(iter->second.decl);
733 }