llvm/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp

//===-- AppleThreadPlanStepThroughObjCTrampoline.cpp-----------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "AppleThreadPlanStepThroughObjCTrampoline.h"

#include "AppleObjCTrampolineHandler.h"
#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Expression/FunctionCaller.h"
#include "lldb/Expression/UtilityFunction.h"
#include "lldb/Target/ABI.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlanRunToAddress.h"
#include "lldb/Target/ThreadPlanStepOut.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"

#include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h"

#include <memory>

usingnamespacelldb;
usingnamespacelldb_private;

// ThreadPlanStepThroughObjCTrampoline constructor
AppleThreadPlanStepThroughObjCTrampoline::
    AppleThreadPlanStepThroughObjCTrampoline(
        Thread &thread, AppleObjCTrampolineHandler &trampoline_handler,
        ValueList &input_values, lldb::addr_t isa_addr, lldb::addr_t sel_addr,
        lldb::addr_t sel_str_addr, llvm::StringRef sel_str)
    :{}

// Destructor
AppleThreadPlanStepThroughObjCTrampoline::
    ~AppleThreadPlanStepThroughObjCTrampoline() = default;

void AppleThreadPlanStepThroughObjCTrampoline::DidPush() {}

bool AppleThreadPlanStepThroughObjCTrampoline::InitializeFunctionCaller() {}

bool AppleThreadPlanStepThroughObjCTrampoline::
    PreResumeInitializeFunctionCaller(void *void_myself) {}

void AppleThreadPlanStepThroughObjCTrampoline::GetDescription(
    Stream *s, lldb::DescriptionLevel level) {}

bool AppleThreadPlanStepThroughObjCTrampoline::ValidatePlan(Stream *error) {}

bool AppleThreadPlanStepThroughObjCTrampoline::DoPlanExplainsStop(
    Event *event_ptr) {}

lldb::StateType AppleThreadPlanStepThroughObjCTrampoline::GetPlanRunState() {}

bool AppleThreadPlanStepThroughObjCTrampoline::ShouldStop(Event *event_ptr) {}

// The base class MischiefManaged does some cleanup - so you have to call it in
// your MischiefManaged derived class.
bool AppleThreadPlanStepThroughObjCTrampoline::MischiefManaged() {}

bool AppleThreadPlanStepThroughObjCTrampoline::WillStop() {}

// Objective-C uses optimized dispatch functions for some common and seldom
// overridden methods.  For instance
//      [object respondsToSelector:];
// will get compiled to:
//      objc_opt_respondsToSelector(object);
// This checks whether the selector has been overridden, directly calling the
// implementation if it hasn't and calling objc_msgSend if it has.
//
// We need to get into the overridden implementation.  We'll do that by 
// setting a breakpoint on objc_msgSend, and doing a "step out".  If we stop
// at objc_msgSend, we can step through to the target of the send, and see if
// that's a place we want to stop.
//
// A couple of complexities.  The checking code might call some other method,
// so we might see objc_msgSend more than once.  Also, these optimized dispatch
// functions might dispatch more than one message at a time (e.g. alloc followed
// by init.)  So we can't give up at the first objc_msgSend.
// That means among other things that we have to handle the "ShouldStopHere" - 
// since we can't just return control to the plan that's controlling us on the
// first step.

AppleThreadPlanStepThroughDirectDispatch ::
    AppleThreadPlanStepThroughDirectDispatch(
        Thread &thread, AppleObjCTrampolineHandler &handler,
        llvm::StringRef dispatch_func_name)
    :{}

AppleThreadPlanStepThroughDirectDispatch::
    ~AppleThreadPlanStepThroughDirectDispatch() {}

void AppleThreadPlanStepThroughDirectDispatch::GetDescription(
    Stream *s, lldb::DescriptionLevel level) {}

bool 
AppleThreadPlanStepThroughDirectDispatch::DoPlanExplainsStop(Event *event_ptr) {}

bool AppleThreadPlanStepThroughDirectDispatch
         ::DoWillResume(lldb::StateType resume_state, bool current_plan) {}

bool AppleThreadPlanStepThroughDirectDispatch::ShouldStop(Event *event_ptr) {}

bool AppleThreadPlanStepThroughDirectDispatch::MischiefManaged() {}