Home | History | Annotate | Download | only in Symbol
      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