Example #1
0
clang::Decl *
ClangASTImporter::CopyDecl (clang::ASTContext *dst_ast,
                            clang::ASTContext *src_ast,
                            clang::Decl *decl)
{
    MinionSP minion_sp;
    
    minion_sp = GetMinion(dst_ast, src_ast);
    
    if (minion_sp)
    {
        clang::Decl *result = minion_sp->Import(decl);
        
        if (!result)
        {
            Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));

            if (log)
            {
                lldb::user_id_t user_id;
                ClangASTMetadata *metadata = GetDeclMetadata(decl);
                if (metadata)
                    user_id = metadata->GetUserID();
                
                if (NamedDecl *named_decl = dyn_cast<NamedDecl>(decl))
                    log->Printf("  [ClangASTImporter] WARNING: Failed to import a %s '%s', metadata 0x%" PRIx64,
                                decl->getDeclKindName(),
                                named_decl->getNameAsString().c_str(),
                                user_id);
                else
                    log->Printf("  [ClangASTImporter] WARNING: Failed to import a %s, metadata 0x%" PRIx64,
                                decl->getDeclKindName(),
                                user_id);
            }
        }
        
        return result;
    }
    
    return nullptr;
}
Example #2
0
clang::Decl *ClangASTImporter::CopyDecl(clang::ASTContext *dst_ast,
                                        clang::ASTContext *src_ast,
                                        clang::Decl *decl) {
  ImporterDelegateSP delegate_sp;

  delegate_sp = GetDelegate(dst_ast, src_ast);

  ASTImporterDelegate::CxxModuleScope std_scope(*delegate_sp, dst_ast);

  if (delegate_sp) {
    clang::Decl *result = delegate_sp->Import(decl);

    if (!result) {
      Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));

      if (log) {
        lldb::user_id_t user_id = LLDB_INVALID_UID;
        ClangASTMetadata *metadata = GetDeclMetadata(decl);
        if (metadata)
          user_id = metadata->GetUserID();

        if (NamedDecl *named_decl = dyn_cast<NamedDecl>(decl))
          log->Printf("  [ClangASTImporter] WARNING: Failed to import a %s "
                      "'%s', metadata 0x%" PRIx64,
                      decl->getDeclKindName(),
                      named_decl->getNameAsString().c_str(), user_id);
        else
          log->Printf("  [ClangASTImporter] WARNING: Failed to import a %s, "
                      "metadata 0x%" PRIx64,
                      decl->getDeclKindName(), user_id);
      }
    }

    return result;
  }

  return nullptr;
}
Example #3
0
void
ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Error &err)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));

    if (log)
        log->Printf("ClangUserExpression::ScanContext()");

    m_target = exe_ctx.GetTargetPtr();

    if (!(m_allow_cxx || m_allow_objc))
    {
        if (log)
            log->Printf("  [CUE::SC] Settings inhibit C++ and Objective-C");
        return;
    }

    StackFrame *frame = exe_ctx.GetFramePtr();
    if (frame == NULL)
    {
        if (log)
            log->Printf("  [CUE::SC] Null stack frame");
        return;
    }

    SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction | lldb::eSymbolContextBlock);

    if (!sym_ctx.function)
    {
        if (log)
            log->Printf("  [CUE::SC] Null function");
        return;
    }

    // Find the block that defines the function represented by "sym_ctx"
    Block *function_block = sym_ctx.GetFunctionBlock();

    if (!function_block)
    {
        if (log)
            log->Printf("  [CUE::SC] Null function block");
        return;
    }

    clang::DeclContext *decl_context = function_block->GetClangDeclContext();

    if (!decl_context)
    {
        if (log)
            log->Printf("  [CUE::SC] Null decl context");
        return;
    }

    if (clang::CXXMethodDecl *method_decl = llvm::dyn_cast<clang::CXXMethodDecl>(decl_context))
    {
        if (m_allow_cxx && method_decl->isInstance())
        {
            if (m_enforce_valid_object)
            {
                lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));

                const char *thisErrorString = "Stopped in a C++ method, but 'this' isn't available; pretending we are in a generic context";

                if (!variable_list_sp)
                {
                    err.SetErrorString(thisErrorString);
                    return;
                }

                lldb::VariableSP this_var_sp (variable_list_sp->FindVariable(ConstString("this")));

                if (!this_var_sp ||
                    !this_var_sp->IsInScope(frame) ||
                    !this_var_sp->LocationIsValidForFrame (frame))
                {
                    err.SetErrorString(thisErrorString);
                    return;
                }
            }

            m_cplusplus = true;
            m_needs_object_ptr = true;
        }
    }
    else if (clang::ObjCMethodDecl *method_decl = llvm::dyn_cast<clang::ObjCMethodDecl>(decl_context))
    {
        if (m_allow_objc)
        {
            if (m_enforce_valid_object)
            {
                lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));

                const char *selfErrorString = "Stopped in an Objective-C method, but 'self' isn't available; pretending we are in a generic context";

                if (!variable_list_sp)
                {
                    err.SetErrorString(selfErrorString);
                    return;
                }

                lldb::VariableSP self_variable_sp = variable_list_sp->FindVariable(ConstString("self"));

                if (!self_variable_sp ||
                    !self_variable_sp->IsInScope(frame) ||
                    !self_variable_sp->LocationIsValidForFrame (frame))
                {
                    err.SetErrorString(selfErrorString);
                    return;
                }
            }

            m_objectivec = true;
            m_needs_object_ptr = true;

            if (!method_decl->isInstanceMethod())
                m_static_method = true;
        }
    }
    else if (clang::FunctionDecl *function_decl = llvm::dyn_cast<clang::FunctionDecl>(decl_context))
    {
        // We might also have a function that said in the debug information that it captured an
        // object pointer.  The best way to deal with getting to the ivars at present it by pretending
        // that this is a method of a class in whatever runtime the debug info says the object pointer
        // belongs to.  Do that here.

        ClangASTMetadata *metadata = ClangASTContext::GetMetadata (&decl_context->getParentASTContext(), function_decl);
        if (metadata && metadata->HasObjectPtr())
        {
            lldb::LanguageType language = metadata->GetObjectPtrLanguage();
            if (language == lldb::eLanguageTypeC_plus_plus)
            {
                if (m_enforce_valid_object)
                {
                    lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));

                    const char *thisErrorString = "Stopped in a context claiming to capture a C++ object pointer, but 'this' isn't available; pretending we are in a generic context";

                    if (!variable_list_sp)
                    {
                        err.SetErrorString(thisErrorString);
                        return;
                    }

                    lldb::VariableSP this_var_sp (variable_list_sp->FindVariable(ConstString("this")));

                    if (!this_var_sp ||
                        !this_var_sp->IsInScope(frame) ||
                        !this_var_sp->LocationIsValidForFrame (frame))
                    {
                        err.SetErrorString(thisErrorString);
                        return;
                    }
                }

                m_cplusplus = true;
                m_needs_object_ptr = true;
            }
            else if (language == lldb::eLanguageTypeObjC)
            {
                if (m_enforce_valid_object)
                {
                    lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));

                    const char *selfErrorString = "Stopped in a context claiming to capture an Objective-C object pointer, but 'self' isn't available; pretending we are in a generic context";

                    if (!variable_list_sp)
                    {
                        err.SetErrorString(selfErrorString);
                        return;
                    }

                    lldb::VariableSP self_variable_sp = variable_list_sp->FindVariable(ConstString("self"));

                    if (!self_variable_sp ||
                        !self_variable_sp->IsInScope(frame) ||
                        !self_variable_sp->LocationIsValidForFrame (frame))
                    {
                        err.SetErrorString(selfErrorString);
                        return;
                    }

                    Type *self_type = self_variable_sp->GetType();

                    if (!self_type)
                    {
                        err.SetErrorString(selfErrorString);
                        return;
                    }

                    ClangASTType self_clang_type = self_type->GetClangForwardType();

                    if (!self_clang_type)
                    {
                        err.SetErrorString(selfErrorString);
                        return;
                    }

                    if (self_clang_type.IsObjCClassType())
                    {
                        return;
                    }
                    else if (self_clang_type.IsObjCObjectPointerType())
                    {
                        m_objectivec = true;
                        m_needs_object_ptr = true;
                    }
                    else
                    {
                        err.SetErrorString(selfErrorString);
                        return;
                    }
                }
                else
                {
                    m_objectivec = true;
                    m_needs_object_ptr = true;
                }
            }
        }
    }
}
Example #4
0
void ClangASTImporter::ASTImporterDelegate::Imported(clang::Decl *from,
                                                     clang::Decl *to) {
  ClangASTMetrics::RegisterClangImport();

  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));

  // Some decls shouldn't be tracked here because they were not created by
  // copying 'from' to 'to'. Just exit early for those.
  if (m_decls_to_ignore.find(to) != m_decls_to_ignore.end())
    return clang::ASTImporter::Imported(from, to);

  lldb::user_id_t user_id = LLDB_INVALID_UID;
  ClangASTMetadata *metadata = m_master.GetDeclMetadata(from);
  if (metadata)
    user_id = metadata->GetUserID();

  if (log) {
    if (NamedDecl *from_named_decl = dyn_cast<clang::NamedDecl>(from)) {
      std::string name_string;
      llvm::raw_string_ostream name_stream(name_string);
      from_named_decl->printName(name_stream);
      name_stream.flush();

      log->Printf("    [ClangASTImporter] Imported (%sDecl*)%p, named %s (from "
                  "(Decl*)%p), metadata 0x%" PRIx64,
                  from->getDeclKindName(), static_cast<void *>(to),
                  name_string.c_str(), static_cast<void *>(from), user_id);
    } else {
      log->Printf("    [ClangASTImporter] Imported (%sDecl*)%p (from "
                  "(Decl*)%p), metadata 0x%" PRIx64,
                  from->getDeclKindName(), static_cast<void *>(to),
                  static_cast<void *>(from), user_id);
    }
  }

  ASTContextMetadataSP to_context_md =
      m_master.GetContextMetadata(&to->getASTContext());
  ASTContextMetadataSP from_context_md =
      m_master.MaybeGetContextMetadata(m_source_ctx);

  if (from_context_md) {
    OriginMap &origins = from_context_md->m_origins;

    OriginMap::iterator origin_iter = origins.find(from);

    if (origin_iter != origins.end()) {
      if (to_context_md->m_origins.find(to) == to_context_md->m_origins.end() ||
          user_id != LLDB_INVALID_UID) {
        if (origin_iter->second.ctx != &to->getASTContext())
          to_context_md->m_origins[to] = origin_iter->second;
      }

      ImporterDelegateSP direct_completer =
          m_master.GetDelegate(&to->getASTContext(), origin_iter->second.ctx);

      if (direct_completer.get() != this)
        direct_completer->ASTImporter::Imported(origin_iter->second.decl, to);

      if (log)
        log->Printf("    [ClangASTImporter] Propagated origin "
                    "(Decl*)%p/(ASTContext*)%p from (ASTContext*)%p to "
                    "(ASTContext*)%p",
                    static_cast<void *>(origin_iter->second.decl),
                    static_cast<void *>(origin_iter->second.ctx),
                    static_cast<void *>(&from->getASTContext()),
                    static_cast<void *>(&to->getASTContext()));
    } else {
      if (m_decls_to_deport && m_decls_already_deported) {
        if (isa<TagDecl>(to) || isa<ObjCInterfaceDecl>(to)) {
          RecordDecl *from_record_decl = dyn_cast<RecordDecl>(from);
          if (from_record_decl == nullptr ||
              !from_record_decl->isInjectedClassName()) {
            NamedDecl *to_named_decl = dyn_cast<NamedDecl>(to);

            if (!m_decls_already_deported->count(to_named_decl))
              m_decls_to_deport->insert(to_named_decl);
          }
        }
      }

      if (to_context_md->m_origins.find(to) == to_context_md->m_origins.end() ||
          user_id != LLDB_INVALID_UID) {
        to_context_md->m_origins[to] = DeclOrigin(m_source_ctx, from);
      }

      if (log)
        log->Printf("    [ClangASTImporter] Decl has no origin information in "
                    "(ASTContext*)%p",
                    static_cast<void *>(&from->getASTContext()));
    }

    if (clang::NamespaceDecl *to_namespace =
            dyn_cast<clang::NamespaceDecl>(to)) {
      clang::NamespaceDecl *from_namespace =
          dyn_cast<clang::NamespaceDecl>(from);

      NamespaceMetaMap &namespace_maps = from_context_md->m_namespace_maps;

      NamespaceMetaMap::iterator namespace_map_iter =
          namespace_maps.find(from_namespace);

      if (namespace_map_iter != namespace_maps.end())
        to_context_md->m_namespace_maps[to_namespace] =
            namespace_map_iter->second;
    }
  } else {
    to_context_md->m_origins[to] = DeclOrigin(m_source_ctx, from);

    if (log)
      log->Printf("    [ClangASTImporter] Sourced origin "
                  "(Decl*)%p/(ASTContext*)%p into (ASTContext*)%p",
                  static_cast<void *>(from), static_cast<void *>(m_source_ctx),
                  static_cast<void *>(&to->getASTContext()));
  }

  if (TagDecl *from_tag_decl = dyn_cast<TagDecl>(from)) {
    TagDecl *to_tag_decl = dyn_cast<TagDecl>(to);

    to_tag_decl->setHasExternalLexicalStorage();
    to_tag_decl->getPrimaryContext()->setMustBuildLookupTable();

    if (log)
      log->Printf(
          "    [ClangASTImporter] To is a TagDecl - attributes %s%s [%s->%s]",
          (to_tag_decl->hasExternalLexicalStorage() ? " Lexical" : ""),
          (to_tag_decl->hasExternalVisibleStorage() ? " Visible" : ""),
          (from_tag_decl->isCompleteDefinition() ? "complete" : "incomplete"),
          (to_tag_decl->isCompleteDefinition() ? "complete" : "incomplete"));
  }

  if (isa<NamespaceDecl>(from)) {
    NamespaceDecl *to_namespace_decl = dyn_cast<NamespaceDecl>(to);

    m_master.BuildNamespaceMap(to_namespace_decl);

    to_namespace_decl->setHasExternalVisibleStorage();
  }

  if (isa<ObjCContainerDecl>(from)) {
    ObjCContainerDecl *to_container_decl = dyn_cast<ObjCContainerDecl>(to);

    to_container_decl->setHasExternalLexicalStorage();
    to_container_decl->setHasExternalVisibleStorage();

    /*to_interface_decl->setExternallyCompleted();*/

    if (log) {
      if (ObjCInterfaceDecl *to_interface_decl =
              llvm::dyn_cast<ObjCInterfaceDecl>(to_container_decl)) {
        log->Printf(
            "    [ClangASTImporter] To is an ObjCInterfaceDecl - attributes "
            "%s%s%s",
            (to_interface_decl->hasExternalLexicalStorage() ? " Lexical" : ""),
            (to_interface_decl->hasExternalVisibleStorage() ? " Visible" : ""),
            (to_interface_decl->hasDefinition() ? " HasDefinition" : ""));
      } else {
        log->Printf(
            "    [ClangASTImporter] To is an %sDecl - attributes %s%s",
            ((Decl *)to_container_decl)->getDeclKindName(),
            (to_container_decl->hasExternalLexicalStorage() ? " Lexical" : ""),
            (to_container_decl->hasExternalVisibleStorage() ? " Visible" : ""));
      }
    }
  }
}
Example #5
0
clang::Decl *
ClangASTImporter::Minion::Imported (clang::Decl *from, clang::Decl *to)
{
    ClangASTMetrics::RegisterClangImport();

    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));

    if (log)
    {
        lldb::user_id_t user_id;
        ClangASTMetadata *metadata = m_master.GetDeclMetadata(from);
        if (metadata)
            user_id = metadata->GetUserID();

        if (NamedDecl *from_named_decl = dyn_cast<clang::NamedDecl>(from))
        {
            std::string name_string;
            llvm::raw_string_ostream name_stream(name_string);
            from_named_decl->printName(name_stream);
            name_stream.flush();

            log->Printf("    [ClangASTImporter] Imported (%sDecl*)%p, named %s (from (Decl*)%p), metadata 0x%" PRIx64,
                        from->getDeclKindName(), static_cast<void*>(to),
                        name_string.c_str(), static_cast<void*>(from),
                        user_id);
        }
        else
        {
            log->Printf("    [ClangASTImporter] Imported (%sDecl*)%p (from (Decl*)%p), metadata 0x%" PRIx64,
                        from->getDeclKindName(), static_cast<void*>(to),
                        static_cast<void*>(from), user_id);
        }
    }

    ASTContextMetadataSP to_context_md = m_master.GetContextMetadata(&to->getASTContext());
    ASTContextMetadataSP from_context_md = m_master.MaybeGetContextMetadata(m_source_ctx);

    if (from_context_md)
    {
        OriginMap &origins = from_context_md->m_origins;

        OriginMap::iterator origin_iter = origins.find(from);

        if (origin_iter != origins.end())
        {
            to_context_md->m_origins[to] = origin_iter->second;

            MinionSP direct_completer = m_master.GetMinion(&to->getASTContext(), origin_iter->second.ctx);

            if (direct_completer.get() != this)
                direct_completer->ASTImporter::Imported(origin_iter->second.decl, to);

            if (log)
                log->Printf("    [ClangASTImporter] Propagated origin (Decl*)%p/(ASTContext*)%p from (ASTContext*)%p to (ASTContext*)%p",
                            static_cast<void*>(origin_iter->second.decl),
                            static_cast<void*>(origin_iter->second.ctx),
                            static_cast<void*>(&from->getASTContext()),
                            static_cast<void*>(&to->getASTContext()));
        }
        else
        {
            if (m_decls_to_deport && m_decls_already_deported)
            {
                if (isa<TagDecl>(to) || isa<ObjCInterfaceDecl>(to))
                {
                    NamedDecl *to_named_decl = dyn_cast<NamedDecl>(to);

                    if (!m_decls_already_deported->count(to_named_decl))
                        m_decls_to_deport->insert(to_named_decl);
                }

            }
            to_context_md->m_origins[to] = DeclOrigin(m_source_ctx, from);

            if (log)
                log->Printf("    [ClangASTImporter] Decl has no origin information in (ASTContext*)%p",
                            static_cast<void*>(&from->getASTContext()));
        }

        if (clang::NamespaceDecl *to_namespace = dyn_cast<clang::NamespaceDecl>(to))
        {
            clang::NamespaceDecl *from_namespace = dyn_cast<clang::NamespaceDecl>(from);

            NamespaceMetaMap &namespace_maps = from_context_md->m_namespace_maps;

            NamespaceMetaMap::iterator namespace_map_iter = namespace_maps.find(from_namespace);

            if (namespace_map_iter != namespace_maps.end())
                to_context_md->m_namespace_maps[to_namespace] = namespace_map_iter->second;
        }
    }
    else
    {
        to_context_md->m_origins[to] = DeclOrigin (m_source_ctx, from);

        if (log)
            log->Printf("    [ClangASTImporter] Sourced origin (Decl*)%p/(ASTContext*)%p into (ASTContext*)%p",
                        static_cast<void*>(from),
                        static_cast<void*>(m_source_ctx),
                        static_cast<void*>(&to->getASTContext()));
    }

    if (TagDecl *from_tag_decl = dyn_cast<TagDecl>(from))
    {
        TagDecl *to_tag_decl = dyn_cast<TagDecl>(to);

        to_tag_decl->setHasExternalLexicalStorage();
        to_tag_decl->setMustBuildLookupTable();

        if (log)
            log->Printf("    [ClangASTImporter] To is a TagDecl - attributes %s%s [%s->%s]",
                        (to_tag_decl->hasExternalLexicalStorage() ? " Lexical" : ""),
                        (to_tag_decl->hasExternalVisibleStorage() ? " Visible" : ""),
                        (from_tag_decl->isCompleteDefinition() ? "complete" : "incomplete"),
                        (to_tag_decl->isCompleteDefinition() ? "complete" : "incomplete"));
    }

    if (isa<NamespaceDecl>(from))
    {
        NamespaceDecl *to_namespace_decl = dyn_cast<NamespaceDecl>(to);

        m_master.BuildNamespaceMap(to_namespace_decl);

        to_namespace_decl->setHasExternalVisibleStorage();
    }

    if (isa<ObjCInterfaceDecl>(from))
    {
        ObjCInterfaceDecl *to_interface_decl = dyn_cast<ObjCInterfaceDecl>(to);

        to_interface_decl->setHasExternalLexicalStorage();
        to_interface_decl->setHasExternalVisibleStorage();

        /*to_interface_decl->setExternallyCompleted();*/

        if (log)
            log->Printf("    [ClangASTImporter] To is an ObjCInterfaceDecl - attributes %s%s%s",
                        (to_interface_decl->hasExternalLexicalStorage() ? " Lexical" : ""),
                        (to_interface_decl->hasExternalVisibleStorage() ? " Visible" : ""),
                        (to_interface_decl->hasDefinition() ? " HasDefinition" : ""));
    }

    return clang::ASTImporter::Imported(from, to);
}